11name : Create PR Preview
2+ description : ' Spins up an Ephemeral Instance for a PR Preview'
23
34inputs :
45 github-token :
56 description : ' Github token used to create PR comments'
67 required : true
7- localstack-api-key :
8- description : ' LocalStack API key used to create the preview environment'
8+ localstack-auth-token :
9+ description : ' LocalStack Auth Token used to create the preview environment'
910 required : false
1011 preview-cmd :
1112 description : ' Command(s) used to create a preview of the PR (can use $AWS_ENDPOINT_URL)'
@@ -68,33 +69,78 @@ runs:
6869 shell : bash
6970 id : create-instance
7071 run : |
72+ AUTH_HEADER="ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-auth-token }}}}"
73+ CONTENT_TYPE_HEADER="content-type: application/json"
74+ API_URL_BASE="https://api.localstack.cloud/v1/compute/instances"
75+
76+ retry() {
77+ local retries=5
78+ local count=0
79+ local wait=5
80+ while [ $count -lt $retries ]; do
81+ "$@"
82+ local exit_code=$?
83+ if [ $exit_code -eq 0 ]; then
84+ return 0
85+ fi
86+ count=$((count + 1))
87+ echo "Command failed with exit code $exit_code. Retrying in $wait seconds... ($count/$retries)"
88+ sleep $wait
89+ done
90+ echo "Command failed after $retries retries."
91+ return 1
92+ }
93+
94+ fetch_instances() {
95+ list_response=$(curl --fail-with-body -s -X GET \
96+ -H "$AUTH_HEADER" \
97+ -H "$CONTENT_TYPE_HEADER" \
98+ "$API_URL_BASE")
99+ if echo "$list_response" | jq -e '.error == true' > /dev/null; then
100+ echo "API returned an error: $list_response"
101+ return 1
102+ fi
103+ }
104+
105+ retry fetch_instances
106+
71107 autoLoadPod="${AUTO_LOAD_POD:-${{ inputs.auto-load-pod }}}"
72108 extensionAutoInstall="${EXTENSION_AUTO_INSTALL:-${{ inputs.extension-auto-install }}}"
73109 lifetime="${{ inputs.lifetime }}"
74110
75- list_response=$(curl -X GET \
76- -H "ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}" \
77- -H "content-type: application/json" \
78- https://api.localstack.cloud/v1/compute/instances)
79-
80111 instance_exists=$(echo "$list_response" | jq --arg NAME "$previewName" '.[] | select(.instance_name == $NAME)')
81112
113+ delete_instance() {
114+ # We expect a 200 on success or 404 if it's already gone. Other codes are errors.
115+ http_code=$(curl -s -o /dev/null -w "%{http_code}" -X DELETE \
116+ -H "$AUTH_HEADER" \
117+ -H "$CONTENT_TYPE_HEADER" \
118+ "$API_URL_BASE/$previewName")
119+ if [ "$http_code" -ne 200 ] && [ "$http_code" -ne 404 ]; then
120+ echo "Error deleting instance, HTTP code: $http_code"
121+ return 1
122+ fi
123+ }
124+
82125 if [ -n "$instance_exists" ]; then
83- del_response=$(curl -X DELETE \
84- -H "ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}" \
85- -H "content-type: application/json" \
86- https://api.localstack.cloud/v1/compute/instances/$previewName)
126+ retry delete_instance
87127 fi
88128
89- response=$(curl -X POST -d "{\"instance_name\": \"${previewName}\", \"lifetime\": ${lifetime} ,\"env_vars\": {\"AUTO_LOAD_POD\": \"${autoLoadPod}\", \"EXTENSION_AUTO_INSTALL\": \"${extensionAutoInstall}\"}}"\
90- -H "ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}" \
91- -H "content-type: application/json" \
92- https://api.localstack.cloud/v1/compute/instances)
93- endpointUrl=$(echo "$response" | jq -r .endpoint_url)
94- if [ "$endpointUrl" = "null" ] || [ "$endpointUrl" = "" ]; then
95- echo "Unable to create preview environment. API response: $response"
96- exit 1
129+ create_instance_func() {
130+ response=$(curl --fail-with-body -s -X POST -d "{\"instance_name\": \"${previewName}\", \"lifetime\": ${lifetime} ,\"env_vars\": {\"AUTO_LOAD_POD\": \"${autoLoadPod}\", \"EXTENSION_AUTO_INSTALL\": \"${extensionAutoInstall}\"}}"\
131+ -H "$AUTH_HEADER" \
132+ -H "$CONTENT_TYPE_HEADER" \
133+ "$API_URL_BASE")
134+
135+ endpointUrl=$(echo "$response" | jq -r .endpoint_url)
136+ if [ "$endpointUrl" = "null" ] || [ "$endpointUrl" = "" ]; then
137+ echo "Unable to create preview environment. API response: $response"
138+ return 1
139+ fi
97140 fi
141+
142+ retry create_instance_func
143+
98144 echo "Created preview environment with endpoint URL: $endpointUrl"
99145
100146 echo $endpointUrl > ./ls-preview-url.txt
@@ -117,9 +163,35 @@ runs:
117163 if : ${{ !cancelled() && steps.create-instance.outcome == 'success' }}
118164 shell : bash
119165 run : |
120- log_response=$(curl -X GET \
121- -H "ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}" \
122- -H "content-type: application/json" \
123- https://api.localstack.cloud/v1/compute/instances/$previewName/logs)
124-
166+ AUTH_HEADER="ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-auth-token }}}}"
167+ CONTENT_TYPE_HEADER="content-type: application/json"
168+ API_URL_BASE="https://api.localstack.cloud/v1/compute/instances"
169+
170+ # TODO code duplication
171+ retry() {
172+ local retries=5
173+ local count=0
174+ local wait=5
175+ while [ $count -lt $retries ]; do
176+ "$@"
177+ local exit_code=$?
178+ if [ $exit_code -eq 0 ]; then
179+ return 0
180+ fi
181+ count=$((count + 1))
182+ echo "Command failed with exit code $exit_code. Retrying in $wait seconds... ($count/$retries)"
183+ sleep $wait
184+ done
185+ echo "Command failed after $retries retries."
186+ return 1
187+ }
188+
189+ fetch_logs() {
190+ log_response=$(curl --fail-with-body -s -X GET \
191+ -H "$AUTH_HEADER" \
192+ -H "$CONTENT_TYPE_HEADER" \
193+ "$API_URL_BASE/$previewName/logs")
194+ }
195+
196+ retry fetch_logs
125197 echo "$log_response" | jq -r '.[].content'
0 commit comments