-
Notifications
You must be signed in to change notification settings - Fork 12
Expand file tree
/
Copy pathaction.yml
More file actions
196 lines (169 loc) · 7.89 KB
/
action.yml
File metadata and controls
196 lines (169 loc) · 7.89 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
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
name: Create PR Preview
description: 'Spins up an Ephemeral Instance for a PR Preview'
inputs:
github-token:
description: 'Github token used to create PR comments'
required: true
localstack-api-key:
description: 'LocalStack Auth Token used to create the preview environment'
required: false
preview-cmd:
description: 'Command(s) used to create a preview of the PR (can use $AWS_ENDPOINT_URL)'
required: false
default: ''
auto-load-pod:
description: 'The pod to load on startup of LocalStack, the env var AUTO_LOAD_POD'
required: false
default: ''
extension-auto-install:
description: 'The extension(s) to automatically install on startup of LocalStack, the env var EXTENSION_AUTO_INSTALL'
required: false
default: ''
lifetime:
description: 'The lifetime of the ephemeral instance, how long the instance should be available for'
required: false
default: '30'
runs:
using: composite
steps:
- name: Initial PR comment
if: inputs.github-token
uses: jenseng/dynamic-uses@5175289a9a87978dcfcb9cf512b821d23b2a53eb # v1
with:
uses: ${{ env.GH_ACTION_ROOT }}/prepare
with: |-
{
"github-token": ${{ toJSON(inputs.github-token) }}
}
- name: Download PR artifact
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7
with:
name: pr-id
- name: Setup preview name
shell: bash
id: preview-name
run: |
prId=$(<pr-id.txt)
repoName=$GITHUB_REPOSITORY
repoNameCleaned=$(echo -n "$repoName" | tr -c '[:alnum:]' '-')
previewName=preview-$repoNameCleaned-$prId
echo "previewName=$previewName" >> $GITHUB_ENV
echo "name=$previewName" >> $GITHUB_OUTPUT
- name: Create preview environment
shell: bash
id: create-instance
run: |
AUTH_HEADER="ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}"
CONTENT_TYPE_HEADER="content-type: application/json"
API_URL_BASE="https://api.localstack.cloud/v1/compute/instances"
source ${{ github.action_path }}/../retry-function.sh
fetch_instances() {
local list_response
list_response=$(curl --fail-with-body -s -X GET \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE_HEADER" \
"$API_URL_BASE")
if [ $? -ne 0 ]; then echo "curl command failed while fetching instances. Response: $list_response" >&2; return 1; fi
if ! check_for_api_error "$list_response" "fetch instances"; then return 1; fi
echo "$list_response"
}
if ! list_response=$(retry fetch_instances); then
echo "Error: Failed to fetch instances after multiple retries."
exit 1
fi
autoLoadPod="${AUTO_LOAD_POD:-${{ inputs.auto-load-pod }}}"
extensionAutoInstall="${EXTENSION_AUTO_INSTALL:-${{ inputs.extension-auto-install }}}"
lifetime="${{ inputs.lifetime }}"
instance_exists=$(echo "$list_response" | jq --arg NAME "$previewName" '.[] | select(.instance_name == $NAME)')
delete_instance() {
# We expect a 200 on success or 404 if it's already gone. Other codes are errors.
local response
response=$(curl --fail-with-body -s -w "\n%{http_code}" -X DELETE \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE_HEADER" \
"$API_URL_BASE/$previewName")
local exit_code=$?
local http_code=$(echo "$response" | tail -n1)
local body=$(echo "$response" | sed '$d')
if [ $exit_code -ne 0 ]; then echo "curl command failed while deleting instance. Response: $body" >&2; return 1; fi
if ! check_for_api_error "$body" "delete instance"; then return 1; fi
if [ "$http_code" -eq 200 ]; then
echo "Instance '$previewName' deleted successfully."
fi
}
if [ -n "$instance_exists" ]; then
echo "Found existing instance using '$previewName', trying to delete the old one..."
if ! retry delete_instance; then
echo "Error: Failed to delete existing instance after multiple retries."
exit 1
fi
fi
create_instance_func() {
local response
response=$(curl --fail-with-body -s -X POST -d "{\"instance_name\": \"${previewName}\", \"lifetime\": ${lifetime} ,\"env_vars\": {\"AUTO_LOAD_POD\": \"${autoLoadPod}\", \"EXTENSION_AUTO_INSTALL\": \"${extensionAutoInstall}\"}}"\
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE_HEADER" \
"$API_URL_BASE")
if [ $? -ne 0 ]; then echo "curl command failed while creating instance. Response: $response" >&2; return 1; fi
if ! check_for_api_error "$response" "create instance"; then return 1; fi
if ! echo "$response" | jq -e 'has("endpoint_url") and (.endpoint_url | test(".+"))' > /dev/null; then
echo "Invalid response from instance creation API: $response" >&2; return 1;
fi
echo "$response"
}
echo "Creating preview environment ..."
if ! response=$(retry create_instance_func); then
echo "Error: Failed to create preview environment after multiple retries."
exit 1
fi
endpointUrl=$(echo "$response" | jq -r .endpoint_url)
echo "Created preview environment with endpoint URL: $endpointUrl"
echo $endpointUrl > ./ls-preview-url.txt
echo "LS_PREVIEW_URL=$endpointUrl" >> $GITHUB_ENV
echo "AWS_ENDPOINT_URL=$endpointUrl" >> $GITHUB_ENV
- name: Upload preview instance URL
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6
with:
name: preview-instance-url
path: ./ls-preview-url.txt
- name: Run preview deployment
if: ${{ inputs.preview-cmd != '' }}
shell: bash
run: |
${{ inputs.preview-cmd }}
- name: Print logs of ephemeral instance
if: ${{ !cancelled() && steps.create-instance.outcome == 'success' }}
shell: bash
env:
previewName: ${{ steps.preview-name.outputs.name }}
run: |
AUTH_HEADER="ls-api-key: ${LOCALSTACK_AUTH_TOKEN:-${LOCALSTACK_API_KEY:-${{ inputs.localstack-api-key }}}}"
CONTENT_TYPE_HEADER="content-type: application/json"
API_URL_BASE="https://api.localstack.cloud/v1/compute/instances"
source ${{ github.action_path }}/../retry-function.sh
fetch_logs() {
local log_response
log_response=$(curl --fail-with-body -s -X GET \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE_HEADER" \
"$API_URL_BASE/$previewName/logs")
if [ $? -ne 0 ]; then echo "curl command failed while fetching logs. Response: $log_response" >&2; return 1; fi
if ! check_for_api_error "$log_response" "fetch logs"; then return 1; fi
# A valid log response must be a JSON array.
if ! echo "$log_response" | jq -e 'if type == "array" then true else false end' > /dev/null; then
echo "Invalid response from logs API (expected a JSON array): $log_response" >&2; return 1;
fi
# Check if the logs contain the "Ready." message, indicating the instance is fully started.
if ! echo "$log_response" | jq -e '.[] | select(.content | contains("Ready."))' > /dev/null; then
echo "Instance is not ready yet, waiting for 'Ready.' message in logs..." >&2
return 1
fi
echo "$log_response"
}
echo "Fetching logs for $previewName ..."
if ! log_response=$(retry fetch_logs); then
echo "Error: Failed to fetch logs after multiple retries."
exit 1
fi
echo "$previewName logs:"
echo "$log_response" | jq -r '.[].content'