-
Notifications
You must be signed in to change notification settings - Fork 0
/
process.yml
275 lines (259 loc) · 25 KB
/
process.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
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
# Orb 'circleci/[email protected]' resolved to 'circleci/[email protected]'
# Orb 'circleci/[email protected]' resolved to 'circleci/[email protected]'
version: 2
jobs:
orb-tools/lint:
docker:
- image: cimg/python:3.11
resource_class: medium
steps:
- checkout
- run:
command: |
#!/bin/bash
if [ ! -d "$ORB_VAL_SOURCE_DIR" ]; then
printf "No source directory located at %s\n" "$ORB_VAL_SOURCE_DIR"
printf "This orb assumes you have built your orb using the Orb Development Kit\n"
printf "https://circleci.com/docs/2.0/orb-author/#orb-development-kit\n"
exit 1
fi
pip install --user yamllint
yamllint "$ORB_VAL_SOURCE_DIR"
environment:
ORB_VAL_SOURCE_DIR: src
name: Linting all YAML files
orb-tools/pack:
docker:
- image: circleci/circleci-cli:0.1.26646
resource_class: medium
steps:
- checkout
- run:
command: |
#!/bin/bash
ORB_DIR=${ORB_VAL_ORB_DIR%/}
ORB_FILE=${ORB_VAL_ORB_FILE_NAME#/}
mkdir -p "$ORB_VAL_ORB_DIR" &&
circleci orb pack --skip-update-check "$ORB_VAL_SOURCE_DIR" >"${ORB_DIR}/${ORB_FILE}"
environment:
ORB_VAL_ORB_DIR: dist
ORB_VAL_ORB_FILE_NAME: orb.yml
ORB_VAL_SOURCE_DIR: src
name: Packing orb source
- run:
command: |
#!/bin/bash
# NOTE: an explicit API token is required for orb validation, for self-hosted CircleCI.
# In the case of CircleCI cloud (https://circleci.com), an API token is not needed.
ORB_DIR=${ORB_VAL_ORB_DIR%/}
ORB_FILE=${ORB_VAL_ORB_FILE_NAME#/}
if [ "https://circleci.com" != "${ORB_VAL_CIRCLECI_API_HOST}" ] && [ -z "${CIRCLE_TOKEN}" ]; then
echo "Please set a valid CIRCLE_TOKEN token from your self-hosted CircleCI."
exit 1
fi
circleci orb validate --host "${ORB_VAL_CIRCLECI_API_HOST:-https://circleci.com}" --token "${CIRCLE_TOKEN:-dummy}" ${ORB_VAL_ORG_ID:+--org-id "$ORB_VAL_ORG_ID"} ${ORB_VAL_ORG_SLUG:+--org-slug "$ORB_VAL_ORG_SLUG"} --skip-update-check "${ORB_DIR}/${ORB_FILE}"
environment:
ORB_VAL_CIRCLECI_API_HOST: https://circleci.com
ORB_VAL_ORB_DIR: dist
ORB_VAL_ORB_FILE_NAME: orb.yml
ORB_VAL_ORG_ID: ''
ORB_VAL_ORG_SLUG: ''
name: Validating orb
- run:
command: |
#!/bin/bash
ORB_DIR=${ORB_VAL_ORB_DIR%/}
# In order to support the possibility of multiple orbs, but with the limitation of requiring a single path to persist to a workspace
# we will first tar the orb source to a single binary file, then untar it to the workspace.
tar_source() {
TMP_SRC_DIR=$(mktemp -d)
tar -czf "${TMP_SRC_DIR}/orb_source.tar.gz" -C "${ORB_DIR}" .
rm -rf "${ORB_DIR}"
mkdir -p "${ORB_DIR}"
mv "${TMP_SRC_DIR}/orb_source.tar.gz" "${ORB_DIR}/orb_source.tar.gz"
rm -rf "${TMP_SRC_DIR}"
}
untar_source() {
TMP_SRC_DIR=$(mktemp -d)
tar -xzf "${ORB_DIR}/orb_source.tar.gz" -C "${TMP_SRC_DIR}"
rm -rf "${ORB_DIR}"
mkdir -p "${ORB_DIR}"
mv "${TMP_SRC_DIR}/"* "${ORB_DIR}/"
rm -rf "${TMP_SRC_DIR}"
}
if [[ $ORB_VAL_TAR == '1' ]]; then
printf "Creating tarball of orb source.\n"
tar_source
pwd
ls -la "${ORB_DIR}"
fi
if [[ $ORB_VAL_UNTAR == '1' ]]; then
printf "Extracting tarball of orb source.\n"
untar_source
pwd
ls -la "${ORB_DIR}"
fi
environment:
ORB_VAL_ORB_DIR: dist
ORB_VAL_TAR: true
name: Prep Workspace
- persist_to_workspace:
paths:
- orb_source.tar.gz
root: dist
orb-tools/review:
docker:
- image: cimg/python:3.11
resource_class: medium
steps:
- checkout
- run:
command: |
checkRequirements() {
if ! which git > /dev/null; then
echo "git is required to install BATS"
exit 1
fi
if [[ $EUID == 0 ]]; then export SUDO=""; else export SUDO="sudo"; fi
}
installBats() {
cd /tmp
git clone https://github.com/bats-core/bats-core.git
cd /tmp/bats-core
$SUDO ./install.sh /usr/local
}
checkInstall() {
if ! which bats > /dev/null; then
echo "BATS has failed to install."
exit 1
fi
echo
echo "BATS-Core installed"
echo
}
runInstallBats() {
checkRequirements
installBats
checkInstall
}
runInstallBats
name: Install BATS-Core
- run:
command: "#!/bin/bash\nif ! command -v bats >/dev/null; then\n\techo 'The \"bats-core\" automation framework must be installed to execute review testing.'\n\techo 'Install bats with the bats orb'\n\texit 1\nfi\nif ! command -v yq >/dev/null; then\n\techo 'The \"yq\" package must be installed to execute review testing.'\n\techo 'Installing \"yq\" automatically...'\n\tYQ_VERSION=v4.20.1\n\tYQ_BIN=yq_linux_amd64\n\twget https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/${YQ_BIN}.tar.gz -O - |\n\t\ttar xz && mv ${YQ_BIN} /usr/bin/yq\nfi\n\nmkdir -p /tmp/orb_dev_kit/review/\necho \"$ORB_VAL_REVIEW_BATS_FILE\" >review.bats\necho \"Reviewing orb best practices\"\necho \"If required, tests can be skipped via their \\\"RCXXX\\\" code with the \\\"exclude\\\" parameter.\"\nbats -T --pretty --report-formatter junit --output /tmp/orb_dev_kit/review ./review.bats\n"
environment:
ORB_VAL_MAX_COMMAND_LENGTH: 64
ORB_VAL_RC_EXCLUDE: ''
ORB_VAL_REVIEW_BATS_FILE: "setup() {\n ORB_DEFAULT_SRC_DIR=\"./src/\"\n ORB_SOURCE_DIR=${ORB_VAL_SOURCE_DIR:-$ORB_DEFAULT_SRC_DIR}\n\t\tORB_SOURCE_DIR=${ORB_SOURCE_DIR%/}\n\tIFS=\",\" read -ra SKIPPED_REVIEW_CHECKS <<<\"${ORB_VAL_RC_EXCLUDE}\"\n}\n\n@test \"RC001: Include source_url in @orb.yml\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC001\" ]]; then\n\t\tskip\n\tfi\n\tresult=$(yq '.display.source_url' \"${ORB_SOURCE_DIR}/@orb.yml\")\n\n\techo 'Set a value for \"source_url\" under the \"display\" key in \"@orb.yml\"'\n\t[[ ! $result = null ]]\n}\n\n@test \"RC002: All components (jobs, commands, executors, examples) must have descriptions\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC002\" ]]; then\n\t\tskip\n\tfi\n\tfor i in $(find \"${ORB_SOURCE_DIR}/jobs\" \"${ORB_SOURCE_DIR}/examples\" \"${ORB_SOURCE_DIR}/commands\" \"${ORB_SOURCE_DIR}/executors\" -name \"*.yml\" 2>/dev/null); do\n\t\tORB_ELEMENT_DESCRIPTION=$(yq '.description' \"$i\")\n\t\tif [[ \"$ORB_ELEMENT_DESCRIPTION\" == null || \"$ORB_ELEMENT_DESCRIPTION\" == '\"\"' ]]; then\n\t\t\techo\n\t\t\techo \"Orb component ${i} is missing a description\"\n\t\t\techo \"While descriptions are not required to create a valid orb, they provide a way to document the purpose of each component and will appear in the orb registry.\"\n\t\t\techo \"Check all orb components for descriptions.\"\n\t\t\texit 1\n\t\tfi\n\tdone\n}\n\n@test \"RC003: All production-ready orbs should contain at least one usage example.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC003\" ]]; then\n\t\tskip\n\tfi\n\tORB_ELEMENT_EXAMPLE_COUNT=$(find ${ORB_SOURCE_DIR}/examples/*.yml -type f 2>/dev/null | wc -l | xargs)\n\tif [ \"$ORB_ELEMENT_EXAMPLE_COUNT\" -lt 1 ]; then\n\t\techo\n\t\techo \"This orb appears to be missing a usage example.\"\n\t\techo \"Add examples under $(${ORB_SOURCE_DIR}/examples) to document how to use the orb for any available use cases.\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC004: Usage example names shoud be descriptive.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC004\" ]]; then\n\t\tskip\n\tfi\n\tfor i in $(find \"${ORB_SOURCE_DIR}examples/*.yml\" -type f >/dev/null 2>&1); do\n\t\tif [[ $i =~ \"example\" ]]; then\n\t\t\techo\n\t\t\techo \"Usage example file name ${i} contains the word 'example'.\"\n\t\t\techo \"Usage example file names should be descriptive and not contain the word 'example'.\"\n\t\t\texit 1\n\t\tfi\n\tdone\n}\n\n@test \"RC005: Write a detailed orb description.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC005\" ]]; then\n\t\tskip\n\tfi\n\tORB_ELEMENT_DESCRIPTION=$(yq '.description' \"${ORB_SOURCE_DIR}/@orb.yml\")\n\tif [[ \"${#ORB_ELEMENT_DESCRIPTION}\" -lt 64 ]]; then\n\t\techo\n\t\techo \"Orb description appears short (under 64 characters).\"\n\t\techo \"Update the description in ${ORB_SOURCE_DIR}/@orb.yml to provide a detailed description of the orb.\"\n\t\techo \"Use the orb description to help users find your orb via search. Try describing what use-case this orb solves for.\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC006: Source URL should be valid.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC006\" ]]; then\n\t\tskip\n\tfi\n\tSOURCE_URL=$(yq '.display.source_url' \"${ORB_SOURCE_DIR}/@orb.yml\")\n\tHTTP_RESPONSE=$(curl -s -L -o /dev/null -w \"%{http_code}\" --retry 5 --retry-delay 5 \"$SOURCE_URL\")\n\tif [[ \"$HTTP_RESPONSE\" -ne 200 ]]; then\n\t\techo\n\t\techo \"Source URL: \\\"$SOURCE_URL\\\" is not reachable.\"\n\t\techo \"Check the Source URL for this orb.\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC007: Home URL should be valid.\" {\n\tHOME_URL=$(yq '.display.home_url' \"${ORB_SOURCE_DIR}/@orb.yml\")\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC007\" || \"$HOME_URL\" == \"null\" ]]; then\n\t\tskip\n\tfi\n\tHTTP_RESPONSE=$(curl -s -L -o /dev/null -w \"%{http_code}\" --retry 5 --retry-delay 5 \"$HOME_URL\")\n\tif [[ \"$HTTP_RESPONSE\" -ne 200 ]]; then\n\t\techo\n\t\techo \"Home URL: \\\"$HOME_URL\\\" is not reachable.\"\n\t\techo \"Check the Home URL for this orb.\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC008: All Run steps should contain a name.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC008\" ]]; then\n\t\tskip\n\tfi\n\tERROR_COUNT=0\n\tfor i in $(find \"${ORB_SOURCE_DIR}/jobs\" \"${ORB_SOURCE_DIR}/commands\" -name \"*.yml\" 2>/dev/null); do\n\t\tORB_COMPONENT_STEPS_COUNT=$(yq '[.steps.[] | .run | select(. != null)] | length' \"$i\")\n\t\tj=0\n\t\twhile [ \"$j\" -lt \"$ORB_COMPONENT_STEPS_COUNT\" ]; do\n\t\t\tORB_COMPONENT_STEP=$(yq \"[.steps.[] | .run | select(. != null)][$j]\" \"$i\")\n\t\t\tORB_COMPONENT_STEP_TYPE=$(echo \"$ORB_COMPONENT_STEP\" | yq -o=json '.' | jq 'type')\n\t\t\tORB_COMPONENT_LINE_NUMBER=$(yq \"[.steps.[] | .run | select(. != null)][$j] | line\" \"$i\")\n\t\t\tORB_COMPONENT_STEP_NAME=$(yq \"[.steps.[] | .run | select(. != null)][$j] | .name\" \"$i\")\n\t\t\tif [[ \"$ORB_COMPONENT_STEP_TYPE\" == '\"string\"' ]]; then\n\t\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\t\techo \"Line number: ${ORB_COMPONENT_LINE_NUMBER}\"\n\t\t\t\techo \"It appears this 'run' step is using 'string' formatting.\"\n\t\t\t\techo \"Consider converting this step into an object with a \\\"name\\\" and \\\"command\\\" property.\"\n\t\t\t\techo ---\n\t\t\t\techo \"$ORB_COMPONENT_STEP\"\n\t\t\t\techo ---\n\t\t\t\tERROR_COUNT=$((ERROR_COUNT + 1))\n\t\t\telif [[ \"$ORB_COMPONENT_STEP_NAME\" == null || \"$ORB_COMPONENT_STEP_NAME\" == '\"\"' ]]; then\n\t\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\t\techo \"Line number: ${ORB_COMPONENT_LINE_NUMBER}\"\n\t\t\t\techo ---\n\t\t\t\tyq \"[.steps.[] | .run | select(. != null)][$j]\" \"$i\"\n\t\t\t\techo ---\n\t\t\t\tERROR_COUNT=$((ERROR_COUNT + 1))\n\t\t\tfi\n\t\t\tj=$((j + 1))\n\t\tdone\n\tdone\n\tif [[ \"$ERROR_COUNT\" -gt 0 ]]; then\n\t\techo\n\t\techo \"Components were found to contain \\\"run\\\" steps without a name.\"\n\t\techo \"While a step does not require a name to be valid, not providing a name will produce a less readable output in the CircleCI UI.\"\n\t\techo \"Consider adding a name to the step to make the output in the UI easier to read.\"\n\t\techo \"https://circleci.com/docs/2.0/configuration-reference/#run\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC009: Complex Run step's commands should be imported.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC009\" ]]; then\n\t\tskip\n\tfi\n\tERROR_COUNT=0\n\tfor i in $(find ${ORB_SOURCE_DIR}/jobs ${ORB_SOURCE_DIR}/commands -name \"*.yml\" 2>/dev/null); do\n\t\tORB_COMPONENT_STEPS_COUNT=$(yq '[.steps.[] | .run | select(. != null)] | length' \"$i\")\n\t\tj=0\n\t\twhile [ \"$j\" -lt \"$ORB_COMPONENT_STEPS_COUNT\" ]; do\n\t\t\tORB_COMPONENT_STEP=$(yq \"[.steps.[] | .run | select(. != null)][$j]\" \"$i\")\n\t\t\tORB_COMPONENT_STEP_TYPE=$(echo \"$ORB_COMPONENT_STEP\" | yq -o=json '.' | jq 'type')\n\t\t\tORB_COMPONENT_LINE_NUMBER=$(yq \"[.steps.[] | .run | select(. != null)][$j] | line\" \"$i\")\n\t\t\tORB_COMPONENT_STEP_COMMAND=$(yq \"[.steps.[] | .run | select(. != null)][$j] | .command\" \"$i\")\n\t\t\tif [[ \"$ORB_COMPONENT_STEP_TYPE\" == '\"string\"' ]]; then\n\t\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\t\techo \"Line number: ${ORB_COMPONENT_LINE_NUMBER}\"\n\t\t\t\techo \"It appears this 'run' step is using 'string' formatting.\"\n\t\t\t\techo \"Consider converting this step into an object with a \\\"name\\\" and \\\"command\\\" property.\"\n\t\t\t\techo ---\n\t\t\t\techo \"$ORB_COMPONENT_STEP\"\n\t\t\t\techo ---\n\t\t\t\tERROR_COUNT=$((ERROR_COUNT + 1))\n\t\t\telif [[ \"${#ORB_COMPONENT_STEP_COMMAND}\" -gt \"${ORB_VAL_MAX_COMMAND_LENGTH}\" ]]; then\n\t\t\t\tif [[ ! \"$ORB_COMPONENT_STEP_COMMAND\" =~ \\<\\<include\\(* ]]; then\n\t\t\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\t\t\techo \"Line number: ${ORB_COMPONENT_LINE_NUMBER}\"\n\t\t\t\t\techo \"This command appears longer than ${ORB_VAL_MAX_COMMAND_LENGTH} characters. Consider using the 'include' syntax.\"\n\t\t\t\t\techo ---\n\t\t\t\t\techo \"$ORB_COMPONENT_STEP_COMMAND\"\n\t\t\t\t\techo ---\n\t\t\t\t\tERROR_COUNT=$((ERROR_COUNT + 1))\n\t\t\t\tfi\n\t\t\tfi\n\t\t\tj=$((j + 1))\n\t\tdone\n\tdone\n\tif [[ \"$ERROR_COUNT\" -gt 0 ]]; then\n\t\techo\n\t\techo \"Components were found to contain \\\"run\\\" steps with a long command that is not imported.\"\n\t\techo \"Did you know you can write your shell scripts and other commands in external files and import them here?\"\n\t\techo \"Writing your scripts externally will allow you to take advantage of syntax highlighting and avoid mixing code and markup.\"\n\t\techo \"https://circleci.com/docs/2.0/using-orbs/#file-include-syntax\"\n\t\texit 1\n\tfi\n}\n\n@test \"RC010: All components (jobs, commands, executors, examples) should be snake_cased.\" {\n\tif [[ \"${SKIPPED_REVIEW_CHECKS[*]}\" =~ \"RC010\" ]]; then\n\t\tskip\n\tfi\n\tfor i in $(find \"${ORB_SOURCE_DIR}/jobs\" \"${ORB_SOURCE_DIR}/commands\" \"${ORB_SOURCE_DIR}/executors\" -name \"*.yml\" 2>/dev/null); do\n\t\t# Check file name for snake_case\n\t\tORB_COMPONENT_FILE_NAME=$(basename \"$i\")\n\t\tif [[ \"$ORB_COMPONENT_FILE_NAME\" == *\"-\"* ]]; then\n\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\techo \"Component names should be snake_cased. Please rename this file to use snake_case.\"\n\t\t\texit 1\n\t\tfi\n\n # Check if the file has parameters, if not skip counting.\n HAS_PARAMETERS=$(yq 'has(\"parameters\")' \"$i\")\n if [[ \"$HAS_PARAMETERS\" == \"false\" ]]; then\n continue\n fi\n\n\t\t# Check parameter keys on component for snake_case\n\t\tORB_COMPONENT_PARAMETERS_COUNT=$(yq '.parameters | keys | .[]' \"$i\")\n\t\tfor j in $ORB_COMPONENT_PARAMETERS_COUNT; do\n\t\t\tif [[ \"$j\" == *\"-\"* ]]; then\n\t\t\t\techo \"File: \\\"${i}\\\"\"\n\t\t\t\techo \" Parameter: \\\"${j}\\\"\"\n\t\t\t\techo \"Parameter keys should be snake_cased. Please rename this parameter to use snake_case.\"\n\t\t\t\texit 1\n\t\t\tfi\n\t\tdone\n\n\tdone\n}\n"
ORB_VAL_SOURCE_DIR: src
name: Review Best Practices
- store_test_results:
path: /tmp/orb_dev_kit/review/
shellcheck/check:
docker:
- image: cimg/base:current
steps:
- checkout
- run:
command: "#!/bin/bash\nRun_ShellCheck() {\n input=\"$1\"\n set --\n \n if [ -n \"$SC_PARAM_EXCLUDE\" ]; then\n set -- \"$@\" \"--exclude=$SC_PARAM_EXCLUDE\"\n fi\n \n if [ \"$SC_PARAM_EXTERNAL_SOURCES\" == \"1\" ]; then\n set -- \"$@\" \"--external-sources\"\n fi\n \n if [ -n \"$SC_PARAM_SHELL\" ]; then\n set -- \"$@\" \"--shell=$SC_PARAM_SHELL\"\n fi\n \n shellcheck \"$@\" --severity=\"$SC_PARAM_SEVERITY\" --format=\"$SC_PARAM_FORMAT\" \"$input\" >> \"$SC_PARAM_OUTPUT\"\n}\n\nCheck_For_ShellCheck() {\n if ! command -v shellcheck &> /dev/null\n then\n echo \"Shellcheck not installed\"\n exit 1\n fi\n}\n\nShellCheck_Files() {\n IFS=$'\\n'\n for file in ${SC_PARAM_IGNORE_DIRS}; do\n trimmed=$(echo \"${file}\" | awk '{$1=$1};1')\n \n if [ -e \"${trimmed}\" ]; then\n set -- \"$@\" \"!\" \"-path\" \"${trimmed}/*.sh\"\n fi\n done\n \n SC_PARAM_PATTERN=\"${SC_PARAM_PATTERN:-\"*.sh\"}\"\n SC_INPUT_FILES=/tmp/sc-input-files\n find \"$SC_PARAM_DIR\" ! -name \"$(printf \"*\\n*\")\" -name \"$SC_PARAM_PATTERN\" -type f \"$@\" | tee \"${SC_INPUT_FILES}\"\n set +e\n while IFS= read -r script\n do\n Run_ShellCheck \"$script\"\n done < \"${SC_INPUT_FILES}\"\n set -eo pipefail\n}\n\nCatch_SC_Errors() {\n if [ -s \"$SC_PARAM_OUTPUT\" ]; then\n printf '\\e[1;31mShellCheck Errors Found\\e[0m\\n'\n cat \"$SC_PARAM_OUTPUT\"\n exit 1\n else\n printf '\\e[1;32mNo ShellCheck Errors Found\\e[0m\\n'\n fi\n}\n\nSC_Main() {\n Check_For_ShellCheck\n ShellCheck_Files\n Catch_SC_Errors\n rm /tmp/sc-input-files\n}\n\n# Will not run if sourced for bats.\n# View src/tests for more information.\nTEST_ENV=\"bats-core\"\nif [ \"${0#*\"$TEST_ENV\"}\" == \"$0\" ]; then\n SC_Main\nfi\n"
environment:
SC_PARAM_DIR: .
SC_PARAM_EXCLUDE: ''
SC_PARAM_EXTERNAL_SOURCES: false
SC_PARAM_FORMAT: tty
SC_PARAM_IGNORE_DIRS: ./.git
SC_PARAM_OUTPUT: shellcheck.log
SC_PARAM_PATTERN: ''
SC_PARAM_SEVERITY: style
SC_PARAM_SHELL: ''
name: Run Shellcheck
- store_artifacts:
destination: shellcheck
path: shellcheck.log
orb-tools/continue:
docker:
- image: circleci/circleci-cli:0.1.26646
resource_class: medium
steps:
- checkout
- attach_workspace:
at: dist
- run:
command: |
#!/bin/bash
ORB_DIR=${ORB_VAL_ORB_DIR%/}
# In order to support the possibility of multiple orbs, but with the limitation of requiring a single path to persist to a workspace
# we will first tar the orb source to a single binary file, then untar it to the workspace.
tar_source() {
TMP_SRC_DIR=$(mktemp -d)
tar -czf "${TMP_SRC_DIR}/orb_source.tar.gz" -C "${ORB_DIR}" .
rm -rf "${ORB_DIR}"
mkdir -p "${ORB_DIR}"
mv "${TMP_SRC_DIR}/orb_source.tar.gz" "${ORB_DIR}/orb_source.tar.gz"
rm -rf "${TMP_SRC_DIR}"
}
untar_source() {
TMP_SRC_DIR=$(mktemp -d)
tar -xzf "${ORB_DIR}/orb_source.tar.gz" -C "${TMP_SRC_DIR}"
rm -rf "${ORB_DIR}"
mkdir -p "${ORB_DIR}"
mv "${TMP_SRC_DIR}/"* "${ORB_DIR}/"
rm -rf "${TMP_SRC_DIR}"
}
if [[ $ORB_VAL_TAR == '1' ]]; then
printf "Creating tarball of orb source.\n"
tar_source
pwd
ls -la "${ORB_DIR}"
fi
if [[ $ORB_VAL_UNTAR == '1' ]]; then
printf "Extracting tarball of orb source.\n"
untar_source
pwd
ls -la "${ORB_DIR}"
fi
environment:
ORB_VAL_ORB_DIR: dist
ORB_VAL_UNTAR: true
name: Prep Workspace
- run:
command: "#!/bin/bash\n\nORB_DIR=${ORB_VAL_ORB_DIR%/}\nORB_FILE=${ORB_VAL_ORB_FILE_NAME#/}\n\n# Create temporary directories and files\nsetup() {\n\tmkdir -p /tmp/circleci/modified\n\trm -rf /tmp/circleci/continue_post.json\n}\n\n# Check for required environment variables and commands\ncheckRequirements() {\n\tif [ -z \"${CIRCLE_CONTINUATION_KEY}\" ]; then\n\t\tprintf \"CIRCLE_CONTINUATION_KEY is required. Make sure setup workflows are enabled.\\n\"\n\t\tprintf \"This Job is designed to be used with the Orb Development Kit.\\n\"\n\t\texit 1\n\tfi\n\n\tif [ -z \"${ORB_VAL_CIRCLECI_API_HOST}\" ]; then\n\t\tprintf \"ORB_VAL_CIRCLECI_API_HOST is required.\\n\"\n\t\tprintf \"If you are using CircleCI Cloud, use default value or set https://circleci.com.\\n\"\n\t\texit 1\n\tfi\n\n\tif ! command -v curl >/dev/null; then\n\t\tprintf \"curl is required to use this command\\n\"\n\t\texit 1\n\tfi\n\n\tif ! command -v jq >/dev/null; then\n\t\tprintf \"jq is required to use this command\\n\"\n\t\texit 1\n\tfi\n\n\tif ! command -v yq >/dev/null; then\n\t\tprintf \"yq is required to use this command\\n\"\n\t\texit 1\n\tfi\n\n\tif [ \"$ORB_VAL_INJECT_ORB\" == 1 ] && [ ! -f \"${ORB_DIR}/${ORB_FILE}\" ]; then\n\t\tprintf \"Inject orb is enabled, but %s is not found in %s.\\n\" \"${ORB_FILE}\" \"${ORB_DIR}\"\n\tfi\n}\n\n# Inject orb source into the configuration\ninjectOrb() {\n\tprintf \"Injecting orb source into configuration.\\n\"\n\tORB_SOURCE=\"${ORB_DIR}/${ORB_FILE}\"\n\texport ORB_SOURCE\n\t# NOTE: load function from yq is only available from v4.x\n\tMODIFIED_CONFIG=\"$(yq '.orbs.[env(ORB_VAL_ORB_NAME)] = load(env(ORB_SOURCE))' \"${ORB_VAL_CONTINUE_CONFIG_PATH}\")\"\n\tprintf \"Modified config:\\n\\n\"\n\tprintf \"%s\" \"${MODIFIED_CONFIG}\"\n\tprintf \"%s\" \"${MODIFIED_CONFIG}\" >\"/tmp/circleci/modified/${ORB_FILE}\"\n\texport MODIFIED_CONFIG_PATH=\"/tmp/circleci/modified/${ORB_FILE}\"\n\tprintf \"\\n\\n\"\n}\n\n# Continue the pipeline using the modified configuration\ncontinuePipeline() {\n\t# Escape the config as a JSON string.\n\tjq -Rs '.' \"${MODIFIED_CONFIG_PATH:-$ORB_VAL_CONTINUE_CONFIG_PATH}\" >/tmp/circleci/config-string.json\n\tjq -n \\\n\t\t--arg continuation \"$CIRCLE_CONTINUATION_KEY\" \\\n\t\t--slurpfile config /tmp/circleci/config-string.json \\\n\t\t'{\"continuation-key\": $continuation, \"configuration\": $config|join(\"\\n\")}' >/tmp/circleci/continue_post.json\n\n\t# Continue the pipeline\n\tprintf \"Continuing pipeline...\\n\"\n\tRESPONSE=$(\n\t\tcurl \\\n\t\t\t-s \\\n\t\t\t-o /dev/stderr \\\n\t\t\t-w '%{http_code}' \\\n\t\t\t-XPOST \\\n\t\t\t-H \"Content-Type: application/json\" \\\n\t\t\t-H \"Accept: application/json\" \\\n\t\t\t--data @/tmp/circleci/continue_post.json \\\n\t\t\t\"${ORB_VAL_CIRCLECI_API_HOST}/api/v2/pipeline/continue\"\n\t)\n\t# Check if the pipeline was successfully continued\n\tif [[ \"$RESPONSE\" -eq 200 ]]; then\n\t\tprintf \"Pipeline successfully continued.\\n\"\n\telse\n\t\tprintf \"ERROR: Response code %s\\n\" \"$RESPONSE\"\n\t\tprintf \"Failed to continue pipeline. Attempt to retry the pipeline, if the problem persists please open an issue on the Orb-Tools Orb repository: https://github.com/CircleCI-Public/orb-tools-orb\\n\"\n\t\texit 1\n\tfi\n\n\t# [[ $(curl \\\n\t# \t-s \\\n\t# \t-o /dev/stderr \\\n\t# \t-w '%{http_code}' \\\n\t# \t-XPOST \\\n\t# \t-H \"Content-Type: application/json\" \\\n\t# \t-H \"Accept: application/json\" \\\n\t# \t--data @/tmp/circleci/continue_post.json \\\n\t# \t\"${ORB_VAL_CIRCLECI_API_HOST}/api/v2/pipeline/continue\") -eq 200 ]] || printf \"Failed to continue pipeline. Attempt to retry the pipeline, if the problem persists please open an issue on the Orb-Tools Orb repository: https://github.com/CircleCI-Public/orb-tools-orb\\n\" >&2 && exit 1\n}\n\n# Print completion message\nprintComplete() {\n\tprintf \"Continuation successful!\\n\"\n\tprintf \"Your orb will now be tested in the next workflow.\\n\"\n\t# shellcheck disable=SC2153\n\tprintf \"View the full pipeline progress: %s/pipelines/%s/%s/%s/%s\\n\" \"${ORB_VAL_CIRCLECI_APP_HOST}\" \"${ORB_VAL_PIPELINE_VCS_TYPE}\" \"${CIRCLE_PROJECT_USERNAME}\" \"${CIRCLE_PROJECT_REPONAME}\" \"${ORB_VAL_PIPELINE_NUMBER}\"\n\n}\n\n# ========================\nsetup\ncheckRequirements\nif [ \"$ORB_VAL_INJECT_ORB\" == 1 ]; then\n\tinjectOrb\nfi\ncontinuePipeline\nprintComplete\n"
environment:
ORB_VAL_CIRCLECI_API_HOST: https://circleci.com
ORB_VAL_CIRCLECI_APP_HOST: https://app.circleci.com
ORB_VAL_CONTINUE_CONFIG_PATH: .circleci/test-deploy.yml
ORB_VAL_INJECT_ORB: true
ORB_VAL_ORB_DIR: dist
ORB_VAL_ORB_FILE_NAME: orb.yml
ORB_VAL_ORB_NAME: pipeline-build-orb
ORB_VAL_PIPELINE_NUMBER: 1
ORB_VAL_PIPELINE_VCS_TYPE: github
name: Continuing To Orb Testing And Deployment
workflows:
lint-pack:
jobs:
- orb-tools/lint:
filters:
tags:
only: /.*/
- orb-tools/pack:
filters:
tags:
only: /.*/
- orb-tools/review:
filters:
tags:
only: /.*/
- shellcheck/check:
filters:
tags:
only: /.*/
- orb-tools/continue:
filters:
tags:
only: /.*/
requires:
- orb-tools/lint
- orb-tools/pack
- orb-tools/review
- shellcheck/check
version: 2