forked from setopsco/github-actions
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathaction.yml
108 lines (94 loc) · 4.24 KB
/
action.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
name: "Setops deployment"
description: "Creates and activates releases for multiple apps within a SetOps stage, performs a predeploy command, waits for the releases to become healthy"
inputs:
setops-organization:
description: The SetOps organization
required: false
setops-project:
description: The SetOps project name
required: true
setops-username:
description: The SetOps username, usually obtained via secrets.SETOPS_USER
required: true
setops-password:
description: The SetOps password, usually obtained via secrets.SETOPS_PASSWORD
required: true
image-digest:
description: The image digest that was returned when pushing the image to the SetOps registry
required: true
setops-stage:
description: The setops stage for the deployment, e.g. production
required: true
setops-apps:
description: The SetOps apps to deploy, space separated, e.g. "app1 app2 app3"
required: true
setops-api-domain:
description: The SetOps API URL to connect to
default: 'api.setops.co'
required: false
number-of-retries-to-wait-for-successful-deployment:
description: Max. number of times to wait for a successful deployment (we sleep for 5 seconds between tries, so 12 equals 1 minute)
required: false
default: "120"
predeploy-command:
description: A predeploy command to be run before activating the releases, e.g. for migrating the database
required: false
runs:
using: "composite"
steps:
- name: "Install Setops"
uses: setopsco/github-actions/setup@v2
with:
setops_api_url: https://${{ inputs.setops-api-domain }}
setops_organization: ${{ inputs.setops-organization }}
setops_username: ${{ inputs.setops-username }}
setops_password: ${{ inputs.setops-password }}
- name: "Setops deployment"
run: |
shopt -s expand_aliases
alias sos='setops -p ${{ inputs.setops-project }} -s ${{ inputs.setops-stage }}'
sos changeset:discard || true
read -r -a apps <<< "${{ inputs.setops-apps }}"
declare -A apps_with_release_id
for app in "${apps[@]}"; do
apps_with_release_id[$app]=$(sos --app "$app" release:create ${{ inputs.image-digest }} | grep -o 'ReleaseID.*' | grep -o '[0-9].*')
done
echo "Changeset for creating releases"
sos changeset:commit
if [ ${#PREDEPLOY_COMMAND} -gt 0 ]; then
echo "Run predeploy command"
first_app=${apps[0]}
release_id_of_first_app=${apps_with_release_id[$first_app]}
task_id=$(sos --app "$first_app" task:run --release "$release_id_of_first_app" --entrypoint sh -- -c "$PREDEPLOY_COMMAND && echo SETOPS_SUCCESS" | tee /dev/stderr | grep -oP '^ID: \K[a-z0-9]+$')
# Checking the expected SETOPS_SUCCESS log after task finished to ensure that all logs are collected
sos --app "$first_app" log -n 50 --task "$task_id" | grep SETOPS_SUCCESS > /dev/null
else
echo "No predeploy command has been configured, skipping."
fi
for app in "${apps[@]}"; do
release_id=${apps_with_release_id[$app]}
sos --app "$app" release:activate "$release_id"
done
echo "Changeset for activating releases"
sos changeset:commit
echo "Waiting for successful releases"
max_times=${{ inputs.number-of-retries-to-wait-for-successful-deployment }}
for app in "${apps[@]}"; do
release_id=${apps_with_release_id[$app]}
# Checking for health state of HEALTHY when health check is configured or otherwise accept UNKNOWN
app_info=$(sos app:info $app)
expected_health_status=UNKNOWN
if echo "$app_info" | grep -A1 "Health Check:" | grep -q " Command:"; then
expected_health_status=HEALTHY
fi
for i in $(seq 1 $max_times); do
sleep 5
if sos app:ps $app | grep -w -E "$release_id.*RUNNING.*$expected_health_status"; then break; fi
echo "Continue waiting for $app release $release_id"
if [ $i = $max_times ]; then exit 1; fi
done
done
env:
# Providing it as an env variable to prevent quoting issues
PREDEPLOY_COMMAND: ${{ inputs.predeploy-command }}
shell: bash