#bash #yaml #gitlab-ci
#bash #yaml #gitlab-ci
Вопрос:
Я пытаюсь создать задание GitLab CI / CD, которое берет скрипт bash из файла YAML и проверяет, правильный ли синтаксис.
У меня есть файл YAML с именем .gitlab-ci.template.yml
со следующим содержимым:
image: node:10.15.3-alpine
stages:
- deploy
deploy:
stage: deploy
script:
- apk_install
- yarn_install
- build
- deploy
.bash: amp;bash |
function apk_install() {
apk add jq git curl grep
}
function yarn_install() {
yarn
}
function build() {
echo "Build"
if [ -f ".gitlab-ci.template.yml" ]; then
echo "Just a dumb test for more lines"
fi
}
function deploy() {
echo "Deploy"
}
before_script:
- *bash
Я хотел бы взять bash
часть и протестировать ее. Я установил shyaml
для получения значений из файла YAML, вот так:
FILE=`cat .gitlab-ci.template.yml | shyaml get-value before_script`
Содержимое $FILE
было бы:
- "function apk_install() {n apk add jq git curl grepn}nnfunction yarn_install() {n yarnn}nfunction build() {n echo "Build"n n if [ -f ".gitlab-ci.template.yml" ]; thenn echo "Just a dumb test for more lines"n fin}nnfunction deploy() {n echo "Deploy"n}n"
Затем с помощью некоторой следующей команды я снова пытаюсь получить действительный файл:
echo $FILE | xargs -0 printf '%bn' | sed 's/\[[:space:]]\[[:space:]]/ /g' | sed 's/\"/"/g' | sed 's/\[[:space:]]//g'
Теперь я могу удалить некоторые символы из начала и конца. Но мне было интересно, есть ли какой-нибудь лучший / более простой способ?
Ответ №1:
Рассматривали ли вы возможность использования yq?
Вот выражение для извлечения сценария оболочки из вашего файла:
yq -r '.[".bash"]' .gitlab-ci.template.yml
Результатом является фактический скрипт. Теперь вам просто нужно передать его в компоновщик bash. Я просмотрел этот сайт для вас, но я не смог найти синтаксический анализатор bash, который часто размещается в сообщениях bash (YMMV). Я нашел ShellChecker через Google, но не оценивал тщательно (так что используйте по своему усмотрению).
В конечном счете, ваш код может выглядеть следующим образом:
yq -r '.[".bash"]' .gitlab-ci.template.yml | ShellChecker # or use your favorite bash linter
Ответ №2:
Для того, чтобы вставить скрипт оболочки, встроенный в GitLab CI YAML, комбинация git
, yq
и shellcheck
выполняет трюк, продемонстрированный в этом задании GitLab CI:
shellcheck:
image: alpine:3.15.0
script:
- |
# shellcheck shell=sh
# Check *.sh
git ls-files --exclude='*.sh' --ignored -c -z | xargs -0r shellcheck -x
# Check files with a shell shebang
git ls-files -c | while IFS= read -r file; do
if head -n1 "${file}" |grep -q "^#\! ?/. (ba|d|k)?sh" ; then
shellcheck -x "${file}"
fi
done
# Check script embedded in GitLab CI YAML named *.gitlab-ci.yml
newline="$(printf 'nq')"
newline=${newline%q}
git ls-files --exclude='*.gitlab-ci.yml' --ignored -c | while IFS= read -r file; do
yq eval '.[] | select(tag=="!!map") | (.before_script,.script,.after_script) | select(. != null ) | path | ".["" join(""].["") ""]"' "${file}" | while IFS= read -r selector; do
script=$(yq eval "${selector} | join("${newline}")" "${file}")
if ! printf '%s' "${script}" | shellcheck -; then
>amp;2 printf "nError in %s in the script specified in %s:n%sn" "${file}" "${selector}" "${script}"
exit 1
fi
done
done
Задание проверит script
, after_script
и before_script
все места, где сценарий оболочки может появиться в GitLab CI YAML. Он выполняет поиск файлов GitLab CI YAML, соответствующих соглашению об именовании *.gitlab-ci.yml
.
Для удобства это задание также проверяет *.sh
файлы, которые начинаются с shebang оболочки.
Я также разместил эту информацию на своем сайте по адресуhttps://candrews.integralblue.com/2022/02/shellcheck-scripts-embedded-in-gitlab-ci-yaml
Ответ №3:
Только что заметил, что я должен получить первое сообщение от before_script
with shyaml
. Итак, я изменил:
FILE=`cat .gitlab-ci.template.yml | shyaml get-value before_script`
Для:
FILE=`cat .gitlab-ci.template.yml | shyaml get-value before_script.0`
Который получит скрипт как есть.