-
Notifications
You must be signed in to change notification settings - Fork 9
370 lines (347 loc) · 22.4 KB
/
project.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
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
################################################################################################
# This workflow attempts to test the steps a user is instructed to go through while deploying
# the Upsun demo project.
################################################################################################
name: Upsun Demo CI
'on':
pull_request:
branches:
- main
types:
- labeled
env:
UPSUN_CLI_NO_INTERACTION: 1
UPSUN_CLI_TOKEN: ${{secrets.DEVREL_USER_UPSUN_TOKEN}}
PHP_VERSION: '8.3'
UPSUN_HOST_REGION: "ca-1"
UPSUN_HOST_SUFFIX: "platform.sh"
UPSUN_USERNAME: "devrel-projects"
GIT_USER_EMAIL: "[email protected]"
GIT_USER_NAME: "DevRel Team Bot"
TEST_PATH: "utils/tests"
ORG_NAME: "demo-test-org"
PROJECT_LOCALDIR: "upsun-demo"
PROJECT_REPO: "platformsh/demo-project"
PROJECT_TITLE: 'Demo Test Run (pr-${{ github.ref_name }})'
DEFAULT_BRANCH: '${{ github.event.pull_request.head.ref }}'
STAGING_SUFFIX: '-staging'
STAGING_BRANCH: '${{ github.event.pull_request.head.ref }}$STAGING_SUFFIX'
DEFAULT_BRANCH_CHAR_LIMIT: 28
SLEEP: 5
BACKEND_PATH: "api/v1/environment"
BLACKFIRE_CLIENT_ID: '${{ secrets.DEVREL_USER_BLACKFIRE_CLIENT_ID }}'
BLACKFIRE_CLIENT_TOKEN: '${{ secrets.DEVREL_USER_BLACKFIRE_CLIENT_TOKEN }}'
jobs:
demo-runthrough:
runs-on: ubuntu-latest
if: ${{ github.event.label.name == 'runthrough' }}
steps:
################################################################################################
# A. Setup Upsun CLI, variables, & other tools.
- name: "[tools] 1. Retrieve local files."
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: "[tools] 2. Set up Homebrew."
id: set-up-homebrew
uses: Homebrew/actions/setup-homebrew@master
- name: "[tools] 3. Install Upsun CLI."
run: |
echo "::notice::Installing Upsun CLI via HomeBrew."
brew install platformsh/tap/upsun-cli
- name: "[tools] 4. Test: The Upsun CLI should be installed and executable."
run: |
echo "::notice::Verifying CLI is installed correctly."
./$TEST_PATH/command_installed.sh upsun
- name: "[tools] 5. Test: Setup Blackfire."
uses: shivammathur/setup-php@v2
with:
php-version: ${{ env.PHP_VERSION }}
extensions: 'blackfire, :xdebug'
tools: 'blackfire, blackfire-player'
- name: "[tools] 6. Test: Setup Default Branch variables."
id: branch_names
run: |
echo "::notice::Ensure branch names are not too long."
if [ "${#DEFAULT_BRANCH}" -gt "$DEFAULT_BRANCH_CHAR_LIMIT" ]; then
echo "Branch name too long"
echo $DEFAULT_BRANCH, "len ${#DEFAULT_BRANCH}", "max $DEFAULT_BRANCH_CHAR_LIMIT"
count=$(($DEFAULT_BRANCH_CHAR_LIMIT-${#STAGING_SUFFIX}-1))
short="${DEFAULT_BRANCH:0:$count}"
DEFAULT_BRANCH="${short}"
STAGING_BRANCH="${short}${STAGING_SUFFIX}"
fi
echo "default_branch=${DEFAULT_BRANCH}" >> $GITHUB_OUTPUT
echo "staging_branch=${STAGING_BRANCH}" >> $GITHUB_OUTPUT
################################################################################################
# B. Setup authenticated Upsun CLI user.
- name: "[setup_cli_auth] 1. Test: an authenticated CLI can retrieve bot user info."
run: |
echo "::notice::Verifying CLI auth - bot can access user info."
RESULT=$(upsun auth:info username)
./$TEST_PATH/compare_strings.sh "$RESULT" "$UPSUN_USERNAME" "Authenticate Upsun CLI user"
- name: "[setup_cli_auth] 2. Test: an authenticated CLI can retrieve organization info."
run: |
echo "::notice::Verifying CLI auth - bot can access test organization info."
RESULT=$(upsun org:info -o $ORG_NAME name)
./$TEST_PATH/compare_strings.sh "$RESULT" "$ORG_NAME" "Authenticate Upsun CLI user"
- name: "[setup_cli_auth] 2. Authenticate Upsun CLI to allow push from workflow."
run: |
echo "::notice::Generating SSH certificate for Upsun CLI."
upsun ssh-cert:load --new -y
touch ~/.ssh/known_hosts
chmod 644 ~/.ssh/known_hosts
ssh-keyscan ssh.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX -v >> ~/.ssh/known_hosts
ssh-keyscan git.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX -v >> ~/.ssh/known_hosts
################################################################################################
# C. Setup local repo.
- name: "[setup_repo] 1. Clone repository into runner."
run: |
echo "::notice::Cloning repo copy into runner."
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.clone")
eval "$cmd"
- name: "[setup_repo] 2. Setup runner Git user."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Setting up Git user."
git config --global user.email "$GIT_USER_EMAIL"
git config --global user.name "$GIT_USER_NAME"
git branch -m ${{ steps.branch_names.outputs.default_branch }}
git branch --show-current
- name: "[setup_repo] 3. Test: Verify Git settings."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Verifying Git settings."
RESULT=$(git config --global user.email)
./$TEST_PATH/compare_strings.sh "$RESULT" "$GIT_USER_EMAIL" "Git config (email)"
RESULT=$(git config --global user.name)
./$TEST_PATH/compare_strings.sh "$RESULT" "$GIT_USER_NAME" "Git config (name)"
RESULT=$(git branch --show-current)
./$TEST_PATH/compare_strings.sh "$RESULT" "${{ steps.branch_names.outputs.default_branch }}" "Git branch"
################################################################################################
# D. Create project. Connect to local repo. Provide access to bot user to the project.
- name: "[create_project] 1. Create a project in the test organization."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::Creating a project in the test organization."
echo "::notice::The project should become a remote repository for the local repo automatically."
upsun project:create -o "$ORG_NAME" \
--title "$PROJECT_TITLE" \
--region "$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX" \
--default-branch ${{ steps.branch_names.outputs.default_branch }}
- name: "[create_project] 2. Test: The create project activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} project.create state complete "create_project"
- name: "[create_project] 3. Test: The create project activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} project.create result success "create_project"
- name: "[create_project] 4. Test: project remote has been set."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
ADDRESS=$(git config remote.upsun.url)
PROJECT_ID=$(upsun project:info id)
EXPECTED="$PROJECT_ID@git.$UPSUN_HOST_REGION.$UPSUN_HOST_SUFFIX:$PROJECT_ID.git"
./$TEST_PATH/compare_strings.sh "$ADDRESS" "$EXPECTED" "project:set-remote git_address"
- name: "[create_project] 5. Test: project remote has been set. Ensure only a single project is defined in org for the current PR."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
# Failure here indicates that a project for another run on the same PR still exists in the org.
EXPECTED=$(upsun project:list -o "$ORG_NAME" --title "$PROJECT_TITLE" --pipe)
RESULT=$(upsun project:info id)
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "project:set-remote local"
- name: "[create_project] 6. Remove remote origin."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git remote remove origin
# @todo: I can't quite get this test to work.
# - name: "[create_project] 7. Test: project is only remote defined on repo."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# # @todo: this test breaks on failure, rather than providing a testable, empty string.
# ADDRESS=$(git config remote.origin.url)
# EXPECTED=""
# ./$TEST_PATH/compare_strings.sh "$ADDRESS" "$EXPECTED" "remote remove origin"
- name: "[create_project] 7. Update production environment name."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
upsun environment:info title "Production (${{ steps.branch_names.outputs.default_branch }})" -e ${{ steps.branch_names.outputs.default_branch }}
# @todo: The tests here are sound, but it takes a moment to get the final complete/success. Some kind of wait is probably
# needed here to 1) if pending --> wait until max, 2) if success, pass test, 3) if fail, fail test.
# The wait logic can be applied for all activity outcomes for 'state'.
# - name: "[create_project] 8. Test: The create production environment access should complete."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# # @todo: a sleep seems to be required here.
# sleep 5
# upsun activity:list
# ./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment_type.access.create state complete "add_bot_user"
# - name: "[create_project] 9. Test: The create production environment access should succeed."
# working-directory: ${{ env.PROJECT_LOCALDIR }}
# run: |
# ./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment_type.access.create result success "add_bot_user"
- name: "[create_project] 10. Test: verify user has been granted access to project."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
ACTIVITY_TYPE="environment_type.access.create"
ACTIVITY_ID=$(upsun activity:list --type $ACTIVITY_TYPE --limit 1 --no-header --columns=id --format plain)
EXPECTED=$(upsun activity:get $ACTIVITY_ID -P parameters.target)
RESULT=$(upsun auth:info id)
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "bot_user_add access"
ACTIVITY_TYPE="environment_type.access.create"
ACTIVITY_ID=$(upsun activity:list --type $ACTIVITY_TYPE --limit 1 --no-header --columns=id --format plain)
EXPECTED=$(upsun activity:get $ACTIVITY_ID -P parameters.role)
RESULT="admin"
./$TEST_PATH/compare_strings.sh "$RESULT" "$EXPECTED" "bot_user_add role"
################################################################################################
# E. First code deploy.
- name: "[first_deploy] 1. Deploy the demo application to Upsun."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
echo "::notice::First push to project."
# @todo: Push through Git, not the CLI, so the exit doesn't break the workflow.
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
git push --force upsun ${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.test.push")
eval "$cmd"
# upsun push -f -y
- name: "[first_deploy] 2. Test: The first deploy activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} push state complete "first_push"
- name: "[first_deploy] 3. Test: The first deploy activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} push result success "first_push"
- name: "[first_deploy] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
cmd=$(cat frontend/src/commands.json | jq -r ".first_deploy.user.get_url")
eval "$cmd"
URL=$(eval "$cmd --pipe")
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=branch -vvv
################################################################################################
# F. Create staging environment.
- name: "[environment_branch] 1. Create preview environment"
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
upsun branch ${{ steps.branch_names.outputs.staging_branch }} --type staging
- name: "[environment_branch] 2. Test: The environment_branch activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} environment.branch state complete "environment_branch"
- name: "[environment_branch] 3. Test: The environment_branch activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} environment.branch result success "environment_branch"
- name: "[environment_branch] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
URL=$(upsun url --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=redis -vvv
- name: "[environment_branch] 5. Update staging environment name."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
upsun environment:info title "Staging (${{ steps.branch_names.outputs.staging_branch }})" -e ${{ steps.branch_names.outputs.staging_branch }}
################################################################################################
# G. Add a service.
- name: "[add_service] 1. Uncomment service configuration block. Commit & push new service."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/uncomment.sh .upsun/config.yaml add_service
export STAGING_BRANCH=${{ steps.branch_names.outputs.staging_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".redis.user.commit")
eval "$cmd"
# Push through Git, not the CLI, so the exit doesn't break the workflow.
cmd=$(cat frontend/src/commands.json | jq -r ".redis.test.push")
eval "$cmd"
- name: "[add_service] 2. Test: The add_service activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} push state complete "add_service"
- name: "[add_service] 3. Test: The add_service activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.staging_branch }} push result success "add_service"
- name: "[add_service_resources] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
URL=$(upsun url --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=merge-production -vvv
################################################################################################
# H. Promote revision to production.
- name: "[merge] 1. Merge staging into production."
working-directory: ${{ env.PROJECT_LOCALDIR }}
continue-on-error: true
run: |
export STAGING_BRANCH=${{ steps.branch_names.outputs.staging_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.merge")
eval "$cmd"
- name: "[merge] 2. Test: The merge activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.merge state complete "merge"
- name: "[merge] 3. Test: The merge activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.merge result success "merge"
################################################################################################
# I. Define production service post_merge resources.
- name: "[prod_service_resources] 1. Set Redis' resources on production."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".merge_production.test.resources_set")
eval "$cmd"
- name: "[prod_service_resources] 2. Test: The update environment resources activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update state complete "init_resources"
- name: "[prod_service_resources] 3. Test: The update environment resources activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update result success "init_resources"
- name: "[prod_service_resources] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git checkout ${{ steps.branch_names.outputs.default_branch }}
git branch
URL=$(upsun url -e ${{ steps.branch_names.outputs.default_branch }} --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=complete -vvv
################################################################################################
# J. Scale down to minimum resources
- name: "[scale] 1. Scale down to minimum resources for Redis"
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
export DEFAULT_BRANCH=${{ steps.branch_names.outputs.default_branch }}
cmd=$(cat frontend/src/commands.json | jq -r ".scale.test.resources_set")
eval "$cmd"
- name: "[scale] 2. Test: The update environment resources activity should complete."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update state complete "init_resources"
- name: "[scale] 3. Test: The update environment resources activity should succeed."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
./utils/tests/activity_outcome.sh ${{ steps.branch_names.outputs.default_branch }} environment.resources.update result success "init_resources"
- name: "[scale] 4. Test: Test responses on demo app using Blackfire Player."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
git checkout ${{ steps.branch_names.outputs.default_branch }}
git branch
URL=$(upsun url -e ${{ steps.branch_names.outputs.default_branch }} --primary --pipe)
sleep $SLEEP
blackfire-player run blackfire.yaml --endpoint="$URL" --variable step=scale -vvv
################################################################################################
# K. Clean up test project.
- name: "[cleanup] 1. Delete project."
working-directory: ${{ env.PROJECT_LOCALDIR }}
run: |
# upsun project:delete -y
cmd=$(cat frontend/src/commands.json | jq -r ".complete.user.delete_project")
eval "$cmd -y"