-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathaction.yml
More file actions
143 lines (132 loc) · 6.59 KB
/
action.yml
File metadata and controls
143 lines (132 loc) · 6.59 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
name: "Setops deployment"
description: "Creates and activates images for multiple apps within a SetOps stage, performs a predeploy command, waits for the new tasks 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
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
setops-definition:
description: The SetOps definition to be applied (leave empty if only new images should be applied)
required: false
setops-version:
description: "The version of SetOps CLI to install. Instead of a full version string you can also specify a constraint string. Examples are: `<0.1.5`, `~0.1.4`, `0.1.x` (all three installing the latest available 0.1.4 version). Defaults to `latest`."
required: false
image-tag:
description: The image tag that was used to tag the image to the SetOps registry
default: ${{ github.sha }}
required: true
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 images, e.g. for migrating the database
required: false
predeploy-command-detach-timeout:
description: Detach timeout for one-off task that runs predeploy command (h = hours, m = minutes, s = second, ms = milliseconds)
required: false
default: "10m"
predeploy-command-cpu:
description: CPU units to provide to the predeploy command. 1024 units are 1 vCPU. Defaults to the configured app CPU units if not passed in.
required: false
predeploy-command-memory:
description: Memory to provide to the predeploy command in MB. Defaults to the configured app memory if not passed in.
required: false
github-token:
description: GitHub token to reduce the risk of rate limits when downloading the requested SetOps CLI
required: false
runs:
using: composite
steps:
- name: Install Setops
uses: setopsco/github-actions/setup@v4
with:
setops_api_url: https://${{ inputs.setops-api-domain }}
setops_organization: ${{ inputs.setops-organization }}
setops_username: ${{ inputs.setops-username }}
setops_password: ${{ inputs.setops-password }}
setops_version: ${{ inputs.setops-version }}
github_token: ${{ inputs.github-token }}
- name: Install yq
run: sudo snap install yq
shell: bash
- name: Setops deployment
run: |
shopt -s expand_aliases
alias sos='setops -p ${{ inputs.setops-project }} -s ${{ inputs.setops-stage }}'
read -r -a apps <<< "${{ inputs.setops-apps }}"
# apply the given definition so the predeploy command will not fail e.g. for a missing app or service
if [ ${#SETOPS_DEFINITION} -gt 0 ]; then
echo "Apply given stage definition: $SETOPS_DEFINITION"
sos stage:apply -f "$SETOPS_DEFINITION" --auto-approve
fi
if [ ${#PREDEPLOY_COMMAND} -gt 0 ]; then
echo "Run predeploy command"
first_app=${apps[0]}
resource_parameters=''
[ ${#PREDEPLOY_COMMAND_CPU} -gt 0 ] && resource_parameters="$resource_parameters --cpu $PREDEPLOY_COMMAND_CPU"
[ ${#PREDEPLOY_COMMAND_MEMORY} -gt 0 ] && resource_parameters="$resource_parameters --memory $PREDEPLOY_COMMAND_MEMORY"
detach_timeout=''
[ ${#PREDEPLOY_DETACH_TIMEOUT} -gt 0 ] && detach_timeout="--detach-timeout $PREDEPLOY_DETACH_TIMEOUT"
task_id=$(sos --app "$first_app" task:run $detach_timeout --image-tag "${{ inputs.image-tag }}" --entrypoint sh $resource_parameters -- -c "$PREDEPLOY_COMMAND && echo SETOPS_SUCCESS" | tee /dev/stderr | grep -oP '^ID: \K[a-z0-9]+$')
echo "Task finished. Checking the expected SETOPS_SUCCESS log 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
COUNT=1
apps_with_image_tags=""
for app in "${apps[@]}"; do
apps_with_image_tags="${apps_with_image_tags}${app}=${{ inputs.image-tag }}"
if [[ "${#apps[@]}" != "$COUNT" ]]; then
apps_with_image_tags="${apps_with_image_tags},"
fi
((COUNT+=1))
done
echo "Apply the updated image-tags: ${apps_with_image_tags}"
sos stage:apply -t $apps_with_image_tags --auto-approve
echo "Waiting for successful deployment"
max_times=${{ inputs.number-of-retries-to-wait-for-successful-deployment }}
for app in "${apps[@]}"; do
# Checking for health state of HEALTHY when health check is configured or otherwise accept UNKNOWN
definition=$(sos stage:dump)
if echo "$definition" | yq -e ".apps[\"$app\"].container.health_check" &> /dev/null; then
echo "Health check detected for app $app - waiting for status RUNNING and health check status HEALTHY"
expected_health_status=HEALTHY
else
echo "No health check detected for app $app - waiting for status RUNNING only"
expected_health_status=UNKNOWN
fi
for i in $(seq 1 $max_times); do
sleep 5
if sos --app $app task | grep -w -E "${{ inputs.image-tag }}.*RUNNING.*$expected_health_status"; then break; fi
echo "Continue waiting for $app with image tag ${{ inputs.image-tag }}"
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 }}
PREDEPLOY_COMMAND_CPU: ${{ inputs.predeploy-command-cpu }}
PREDEPLOY_COMMAND_MEMORY: ${{ inputs.predeploy-command-memory }}
PREDEPLOY_DETACH_TIMEOUT: ${{ inputs.predeploy-command-detach-timeout }}
SETOPS_DEFINITION: ${{ inputs.setops-definition }}
shell: bash