aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-x.github/workflows/check-shell.sh111
-rw-r--r--.github/workflows/exception-list.txt4
-rw-r--r--.github/workflows/functions.sh93
-rw-r--r--.github/workflows/integration_test.yml23
-rw-r--r--.github/workflows/script-list.txt38
-rw-r--r--.github/workflows/shellcheck_test.yml54
6 files changed, 323 insertions, 0 deletions
diff --git a/.github/workflows/check-shell.sh b/.github/workflows/check-shell.sh
new file mode 100755
index 00000000..76e95bb0
--- /dev/null
+++ b/.github/workflows/check-shell.sh
@@ -0,0 +1,111 @@
+#!/bin/bash
+
+SCRIPT_DIR="$(dirname "$(readlink -f "$0")")"
+
+. $SCRIPT_DIR/functions.sh
+
+git_base=$1
+git_head=$2
+
+# ------------ #
+# FILE PATHS #
+# ------------ #
+
+# https://github.com/actions/runner/issues/342
+# get names of files from PR (excluding deleted files)
+git diff --name-only --diff-filter=db "$git_base".."$git_head" > ../pr-changes.txt
+
+# Find modified shell scripts
+list_of_changes=()
+file_to_array "../pr-changes.txt" "list_of_changes" 0
+list_of_scripts=()
+file_to_array "$SCRIPT_DIR/script-list.txt" "list_of_scripts" 1
+
+# Create list of scripts for testing
+list_of_changed_scripts=()
+for file in "${list_of_changes[@]}"; do
+ is_it_script "$file" "${list_of_scripts[@]}" && list_of_changed_scripts+=("./${file}") && continue
+ check_extension "$file" && list_of_changed_scripts+=("./${file}") && continue
+ check_shebang "$file" && list_of_changed_scripts+=("./${file}")
+done
+
+# Expose list_of_changed_scripts[*] for use inside GA workflow
+echo "LIST_OF_SCRIPTS=${list_of_changed_scripts[*]}" >> "$GITHUB_ENV"
+
+# Get list of exceptions
+list_of_exceptions=()
+file_to_array "$SCRIPT_DIR/exception-list.txt" "list_of_exceptions" 1
+string_of_exceptions=$(join_by , "${list_of_exceptions[@]}")
+
+echo -e "\n"
+echo ":::::::::::::::::::::"
+echo -e "::: ${WHITE}Shellcheck CI${NOCOLOR} :::"
+echo ":::::::::::::::::::::"
+echo -e "\n"
+
+echo -e "${WHITE}Changed shell scripts:${NOCOLOR}"
+echo "${list_of_changed_scripts[@]}"
+echo -e "${WHITE}List of shellcheck exceptions:${NOCOLOR}"
+echo "${string_of_exceptions}"
+echo -e "\n"
+
+# ------------ #
+# SHELLCHECK #
+# ------------ #
+
+# sed part is to edit shellcheck output so csdiff/csgrep knows it is shellcheck output (--format=gcc)
+shellcheck --format=gcc --exclude="${string_of_exceptions}" "${list_of_changed_scripts[@]}" 2> /dev/null | sed -e 's|$| <--[shellcheck]|' > ../pr-br-shellcheck.err
+
+# make destination branch
+git checkout -q -b ci_br_dest "$git_base"
+
+shellcheck --format=gcc --exclude="${string_of_exceptions}" "${list_of_changed_scripts[@]}" 2> /dev/null | sed -e 's|$| <--[shellcheck]|' > ../dest-br-shellcheck.err
+
+# ------------ #
+# VALIDATION #
+# ------------ #
+
+exitstatus=0
+echo ":::::::::::::::::::::::::"
+echo -e "::: ${WHITE}Validation Output${NOCOLOR} :::"
+echo ":::::::::::::::::::::::::"
+echo -e "\n"
+
+
+# Check output for Fixes
+csdiff --fixed "../dest-br-shellcheck.err" "../pr-br-shellcheck.err" > ../fixes.log
+
+# Expose number of solved issues for use inside GA workflow
+no_fixes=$(grep -Eo "[0-9]*" < <(csgrep --mode=stat ../fixes.log))
+echo "NUMBER_OF_SOLVED_ISSUES=${no_fixes:-0}" >> "$GITHUB_ENV"
+
+if [ "$(cat ../fixes.log | wc -l)" -ne 0 ]; then
+ echo -e "${GREEN}Fixed bugs:${NOCOLOR}"
+ csgrep ../fixes.log
+ echo "---------------------"
+else
+ echo -e "${YELLOW}No Fixes!${NOCOLOR}"
+ echo "---------------------"
+fi
+echo -e "\n"
+
+
+# Check output for added bugs
+csdiff --fixed "../pr-br-shellcheck.err" "../dest-br-shellcheck.err" > ../bugs.log
+
+# Expose number of added issues for use inside GA workflow
+no_issues=$(grep -Eo "[0-9]*" < <(csgrep --mode=stat ../bugs.log))
+echo "NUMBER_OF_ADDED_ISSUES=${no_issues:-0}" >> "$GITHUB_ENV"
+
+if [ "$(cat ../bugs.log | wc -l)" -ne 0 ]; then
+ echo -e "${RED}Added bugs, NEED INSPECTION:${NOCOLOR}"
+ csgrep ../bugs.log
+ echo "---------------------"
+ exitstatus=1
+else
+ echo -e "${GREEN}No bugs added Yay!${NOCOLOR}"
+ echo "---------------------"
+ exitstatus=0
+fi
+
+exit $exitstatus
diff --git a/.github/workflows/exception-list.txt b/.github/workflows/exception-list.txt
new file mode 100644
index 00000000..5b093820
--- /dev/null
+++ b/.github/workflows/exception-list.txt
@@ -0,0 +1,4 @@
+# List of Shelcheck codes which should be excluded from ci output
+# Avoid spaces in list since they are counted as comment
+SC1090 # Ignore when shellcheck can't follow non-constant source e.g. ``. "${path}"``
+SC2148 # Ignore missing shebang
diff --git a/.github/workflows/functions.sh b/.github/workflows/functions.sh
new file mode 100644
index 00000000..d6128486
--- /dev/null
+++ b/.github/workflows/functions.sh
@@ -0,0 +1,93 @@
+# shellcheck shell=bash
+# Function to check whether input param is on list of shell scripts
+# $1 - <string> absolute path to file
+# $@ - <array of strings> list of strings to compare with
+# $? - return value - 0 when succes
+is_it_script () {
+ [ $# -le 1 ] && return 1
+ local file="$1"
+ shift
+ local scripts=("$@")
+
+ [[ " ${scripts[*]} " =~ " ${file} " ]] && return 0 || return 2
+}
+
+# Function to check if given file has .sh extension
+# https://stackoverflow.com/a/407229
+# $1 - <string> absolute path to file
+# $? - return value - 0 when succes
+check_extension () {
+ [ $# -le 0 ] && return 1
+ local file="$1"
+
+ [ "${file: -3}" == ".sh" ] && return 0 || return 2
+}
+
+# Function to check if given file contain shell shebang (bash or sh)
+# https://unix.stackexchange.com/a/406939
+# $1 - <string> absolute path to file
+# $? - return value - 0 when succes
+check_shebang () {
+ [ $# -le 0 ] && return 1
+ local file="$1"
+
+ if IFS= read -r line < "./${file}" ; then
+ case $line in
+ "#!/bin/bash") return 0;;
+ "#!/bin/sh") return 0;;
+ *) return 1
+ esac
+ fi
+}
+
+# Function to prepare string from array of strings where first argument specify one character separator
+# https://stackoverflow.com/a/17841619
+# $1 - <char> Character used to join elements of array
+# $@ - <array of string> list of strings
+# return value - string
+join_by () {
+ local IFS="$1"
+ shift
+ echo "$*"
+}
+
+# Function to get rid of comments represented by '#'
+# $1 - file path
+# $2 - name of variable where will be stored result array
+# $3 - value 1|0 - does file content inline comments?
+# $? - return value - 0 when succes
+file_to_array () {
+ [ $# -le 2 ] && return 1
+ local output=()
+
+ [ "$3" -eq 0 ] && readarray output < <(grep -v "^#.*" "$1") # fetch array with lines from file while excluding '#' comments
+ [ "$3" -eq 1 ] && readarray output < <(cut -d ' ' -f 1 < <(grep -v "^#.*" "$1")) # fetch array with lines from file while excluding '#' comments
+ clean_array "$2" "${output[@]}" && return 0
+}
+
+# Function to get rid of spaces and new lines from array elements
+# https://stackoverflow.com/a/9715377
+# https://stackoverflow.com/a/19347380
+# https://unix.stackexchange.com/a/225517
+# $1 - name of variable where will be stored result array
+# $@ - source array
+# $? - return value - 0 when succes
+clean_array () {
+ [ $# -le 2 ] && return 1
+ local output="$1"
+ shift
+ local input=("$@")
+
+ for i in "${input[@]}"; do
+ eval $output+=\("${i//[$'\t\r\n ']}"\)
+ done
+}
+
+# Color aliases use echo -e to use them
+export NOCOLOR='\033[0m'
+export RED='\033[0;31m'
+export GREEN='\033[0;32m'
+export ORANGE='\033[0;33m'
+export BLUE='\033[0;34m'
+export YELLOW='\033[1;33m'
+export WHITE='\033[1;37m'
diff --git a/.github/workflows/integration_test.yml b/.github/workflows/integration_test.yml
new file mode 100644
index 00000000..0975a35c
--- /dev/null
+++ b/.github/workflows/integration_test.yml
@@ -0,0 +1,23 @@
+# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+name: Integration test
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+ branches:
+ - master
+ - rhel*-branch
+ release:
+ types: [published, created]
+
+jobs:
+ buildCheck:
+ runs-on: ubuntu-20.04
+ steps:
+ - name: Repository checkout
+ uses: actions/checkout@v2
+ - name: Install dependencies
+ run: sudo apt update && sudo apt install -y libpopt-dev gettext
+ - name: Build & install
+ run: make all && make install DESTDIR=/tmp/initscripts
diff --git a/.github/workflows/script-list.txt b/.github/workflows/script-list.txt
new file mode 100644
index 00000000..053672df
--- /dev/null
+++ b/.github/workflows/script-list.txt
@@ -0,0 +1,38 @@
+# Tracker of all shell scripts in this repository
+# Every new script should be added in order to test it with ci
+# Avoid spaces in list since they are counted as comment
+etc/rc.d/init.d/functions
+etc/rc.d/init.d/network
+network-scripts/ifdown-bnep
+network-scripts/ifdown-ippp
+network-scripts/ifdown-post
+network-scripts/ifdown-sit
+network-scripts/ifup
+network-scripts/ifup-bnep
+network-scripts/ifup-eth
+network-scripts/ifup-ipv6
+network-scripts/ifup-plusb
+network-scripts/ifup-routes
+network-scripts/ifup-tunnel
+network-scripts/init.ipv6-global
+network-scripts/network-functions-ipv6
+network-scripts/ifdown
+network-scripts/ifdown-eth
+network-scripts/ifdown-ipv6
+network-scripts/ifdown-routes
+network-scripts/ifdown-tunnel
+network-scripts/ifup-aliases
+network-scripts/ifup-ctc
+network-scripts/ifup-ippp
+network-scripts/ifup-plip
+network-scripts/ifup-post
+network-scripts/ifup-sit
+network-scripts/ifup-wireless
+network-scripts/network-functions
+usr/libexec/import-state
+usr/libexec/loadmodules
+usr/libexec/netconsole
+usr/libexec/readonly-root
+usr/sbin/service
+.ci/check-shell.sh
+.ci/functions.sh
diff --git a/.github/workflows/shellcheck_test.yml b/.github/workflows/shellcheck_test.yml
new file mode 100644
index 00000000..bc4a4fd6
--- /dev/null
+++ b/.github/workflows/shellcheck_test.yml
@@ -0,0 +1,54 @@
+# GA doc: https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
+# github-script doc: https://github.com/marketplace/actions/github-script
+name: Shellcheck test
+on:
+ pull_request:
+ branches:
+ - master
+ - rhel*-branch
+ - new-feature-actions-PR-comments
+
+jobs:
+ shellCheck:
+ runs-on: ubuntu-20.04
+ defaults:
+ run:
+ shell: bash
+
+ steps:
+ - name: Install dependencies
+ run: sudo apt update && sudo apt-get install -y cmake help2man libboost-dev libboost-filesystem-dev libboost-program-options-dev libboost-python-dev libboost-regex-dev tree
+
+ - name: Clone csdiff repository
+ run: cd ../ && git clone --depth=1 https://github.com/csutils/csdiff.git && cd -
+
+ - name: Build and install csdiff
+ run: cd ../csdiff && sudo make && sudo make install && cd -
+
+ - name: Repository checkout
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ ref: ${{ github.event.pull_request.head.sha }}
+
+ - name: Run shell-check test
+ run: |
+ bash ./.github/workflows/check-shell.sh ${{ github.event.pull_request.base.sha }} ${{ github.event.pull_request.head.sha }}
+
+ # ! Disable Output, since there is a problem with permissions and GITHUB_TOKEN
+ # ! https://github.blog/changelog/2021-04-20-github-actions-control-permissions-for-github_token/
+ # TODO: possible solution is to use probot framework to build github app/action
+ # TODO: Set labels based on env.NUMBER_OF_ADDED_ISSUES and env.NUMBER_OF_SOLVED_ISSUES
+ # - name: Output test results
+ # # Run this step even if previous failed
+ # if: always()
+ # uses: actions/github-script@v5
+ # with:
+ # # Colored GH comments: https://stackoverflow.com/a/39413824
+ # script: |
+ # github.rest.issues.createComment({
+ # issue_number: context.issue.number,
+ # owner: context.repo.owner,
+ # repo: context.repo.repo,
+ # body: '```diff\n@@ Shellcheck test summary @@\n- added issues: ${{ env.NUMBER_OF_ADDED_ISSUES }}\n+ solved issues: ${{ env.NUMBER_OF_SOLVED_ISSUES }}\n\n# list of edited shell scripts:\n${{ env.LIST_OF_SCRIPTS }}\n```'
+ # })