From 1f38d11af83d3758c6b12e8dbad8ba05d60d9247 Mon Sep 17 00:00:00 2001 From: Maxim Likhachev Date: Fri, 12 Jun 2020 19:33:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A1=D0=BA=D1=80=D0=B8=D0=BF=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=8B=20?= =?UTF-8?q?=D1=81=20GitLab?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 2 ++ gitlab-ci-graph | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gitlab-ci-linter | 36 +++++++++++++++++++++++++++++++++++ todolist | 2 +- 4 files changed, 96 insertions(+), 1 deletion(-) create mode 100755 gitlab-ci-graph create mode 100755 gitlab-ci-linter diff --git a/README.md b/README.md index fcb9c50..e4201a2 100644 --- a/README.md +++ b/README.md @@ -76,6 +76,8 @@ will create the symbolic link for each script in the \ directory. ## Development tools - [doctools2man](doctools2man) converts doctool to man pages. +- [gitlab-ci-graph](gitlab-ci-graph) draws a graph of the GitLab CI Pipeline file. +- [gitlab-ci-linter](gitlab-ci-linter) checks Gitlab CI Pipeline syntax via GitLab API. - [how](how) shows dev cheat sheets using [cheat.sh](https://cheat.sh). - [robodoc2html](robodoc2html) converts a documentation in the robodoc format into html. - [todolist](todolist) shows all `TODO` notes in current git repository. diff --git a/gitlab-ci-graph b/gitlab-ci-graph new file mode 100755 index 0000000..e6d9f8c --- /dev/null +++ b/gitlab-ci-graph @@ -0,0 +1,57 @@ +#!/bin/bash + +# +# Show graph of GitLab CI Pipeline +# + +# Requirements: +# - jq +# - python-yq (pip install yq) +# - graph-easy + +GITLAB_CI=${1:-.gitlab-ci.yml} + +if [ ! -f "$GITLAB_CI" ]; then + echo "USAGE: $(basename "$0") gitlab-ci.yml." + echo " Or run this script inside CI directory." + exit +fi + +mapfile -t stages < <(yq -c -r '.stages[]' <.gitlab-ci.yml | expand | sed -e 's/^\s*-\s\+//') 2>&- + +echo + +{ + +printf "[BEGIN] { label: '*'; } ==> "; +printf "[%s] ==> " "${stages[@]^^}"; +printf "[END] {label: '*'; }\n" + +for stage in "${stages[@]}"; do + mapfile -t jobs < <(yq -r '. as $input + | keys[] + | [., $input[.]] + | select(.[1].stage?=='\""$stage"\"') + | .[0]' <"$GITLAB_CI" 2>&-) + + for job in "${jobs[@]}"; do + echo "[${stage^^}] --> [${job}]" + + when=$(yq -c -r '.['\""$job"\"'] + | select(.when?) + | [.when] + | flatten' <"$GITLAB_CI" \ + | sed -E 's/\["|"]//g; s/","/ AND /g') + + yq -c -r '.['\""$job"\"'] + | select(.needs?) + | [.needs] + | flatten' <"$GITLAB_CI" \ + | sed "s/\"//g; s/,/],[/g; s/$/ -- $when --> { text-wrap: 10; } \[$job\]/" + done +done + +} | graph-easy + +echo + diff --git a/gitlab-ci-linter b/gitlab-ci-linter new file mode 100755 index 0000000..3fdf128 --- /dev/null +++ b/gitlab-ci-linter @@ -0,0 +1,36 @@ +#!/bin/bash + +#Создан: Чт 11 июн 2020 16:05:25 +#Изменён: пт 12 июн 2020 19:28:15 + +# +# GitLab Pipeline Linter +# +# Requirements: +# - curl +# - jq +# + +# GitLab Pipeline Linter API endpoint. Official gitlab.com by default +[ -z "$GITLAB_URL" ] && GITLAB_URL="https://gitlab.com/api/v4/ci/lint" + +PIPELINE=${1:-.gitlab-ci.yml} + +if [ ! -f "$PIPELINE" ]; then + echo "USAGE: $(basename "$0") gitlab-ci.yml." + echo " Or run this script inside CI directory." + exit +fi + +CONTENT=$(printf '{ "content": %s }' "$(jq -aRs . <"$PIPELINE")") + +RESPONSE=$(curl -sq --header "Content-Type: application/json" "$GITLAB_URL" --data "$CONTENT") + +STATUS=$(jq -r .status <<<"$RESPONSE") + +if [ "$STATUS" != "valid" ]; then + echo -n "ERROR: Pipeline $PIPELINE is invalid: " + jq -r '.errors[]' <<<"$RESPONSE" + exit 1 +fi + diff --git a/todolist b/todolist index c4ae293..33a32bb 100755 --- a/todolist +++ b/todolist @@ -5,6 +5,6 @@ [ -n "$1" ] && cd "$1" if git rev-parse --show-toplevel &>/dev/null; then - grep -n -R "^[[:space:]]*[#/\"-]*[[:space:]]*TODO:" + grep -n -R "^[[:space:]]*[#/\"-]*[[:space:]]*TODO:" . fi