Skip to content

Gh work

Gh work #31

name: ShellCheck Debian package scripts
env:
# This is a space separated string for multiple globs
# Do not use curly braces as they will be treated as literal string in `git ls-files ${GLOBS_TO_SHELLCHECK}`
# Assumption in this workflow: the resolved filepaths do not contain spaces.
GLOBS_TO_SHELLCHECK: "debian/cherry-pick debian/*.config debian/*.postinst debian/*.postrm debian/*.preinst debian/*.prerm packages/debian/*.postrm"
defaults:
run:
shell: bash -e {0}
on:
pull_request:
# There is a known bug in Github but it will most probably not affect out use case
# https://github.com/orgs/community/discussions/118623#discussioncomment-9087833
# When there are 2 PRs using the same source branch (actually the same head SHA to be more specific), with the base branch in one PR matching
# on.pull_request.branches and thee base branch in the second PR not matching this key,
# then the second PR will show these checks that were triggered by the first PR but not the second PR.
branches:
- 'ubuntu/**'
push:
branches:
- 'ubuntu/**'
concurrency:
group: 'ci-${{ github.workflow }}-${{ github.ref }}'
cancel-in-progress: true
# Note: No need to specify the shell option in the shellcheck command
# as shellcheck reads and uses the shebang at the top of the linted scripts.
jobs:
shellcheck-on-matching-and-changed-files:
name: ShellCheck on matching files that have changed
runs-on: ubuntu-24.04
steps:
- name: Repository checkout
uses: actions/checkout@v4
- name: Get all matching changed files
id: matching-changed-files
# make sure to use a SHA not a version
uses: tj-actions/changed-files@24d32ffd492484c1d75e0c0b894501ddb9d30d62
with:
files: ${{ env.GLOBS_TO_SHELLCHECK }}
files_separator: " "
- name: Run shellcheck on the matching changed files
env:
ALL_CHANGED_FILES: ${{ steps.matching-changed-files.outputs.all_changed_and_modified_files }}
run: |
if [ -z "${ALL_CHANGED_FILES}" ]
then
echo "There are no changed files in the repo which match the glob pattern \'${GLOBS_TO_SHELLCHECK}\' so shellcheck will not run"
else
echo "The changed and modified (including deleted) files are ${ALL_CHANGED_FILES}"
echo "The globs used are ${GLOBS_TO_SHELLCHECK}"
# Define high-water marks for expected lint info and warn levels
declare -A INFO_LIMITS WARN_LIMITS
INFO_LIMITS["debian/cherry-pick"]=5
WARN_LIMITS["debian/cherry-pick"]=4
INFO_LIMITS["debian/cloud-init-base.config"]=3
WARN_LIMITS["debian/cloud-init-base.config"]=7
INFO_LIMITS["debian/cloud-init-base.postinst"]=16
WARN_LIMITS["debian/cloud-init-base.postinst"]=17
INFO_LIMITS["debian/cloud-init-base.preinst"]=15
WARN_LIMITS["debian/cloud-init-base.preinst"]=21
ALL_NEW_LINTS=""
for script_name in ${ALL_CHANGED_FILES}; do
NEW_SCRIPT_LINTS=""
if [ -f ${script_name} ]; then
# Only error when lint counts are greater than limits
info_limit=0
warn_limit=0
# Respect and defined limits, otherwise exit non-zero
if [[ -v INFO_LIMITS[$script_name] ]]; then
info_limit=${INFO_LIMITS[$script_name]}
fi
if [[ -v WARN_LIMITS[$script_name] ]]; then
warn_limit=${WARN_LIMITS[$script_name]}
fi
shellcheck ${script_name} > output.txt || true
lint_info_count=$( grep -c '(info)' output.txt ) || true
lint_warn_count=$( grep -c '(warning)' output.txt ) || true
if [ $lint_info_count -gt $info_limit ]; then
NEW_SCRIPT_LINTS+="shellcheck $script_name- too many (info) lints: $lint_info_count\n"
fi
if [ $lint_warn_count -gt $warn_limit ]; then
NEW_SCRIPT_LINTS+="shellcheck $script_name- too many (warning) lints: $lint_warn_count\n"
fi
fi
if [ -n "$NEW_SCRIPT_LINTS" ]; then
ALL_NEW_LINTS+=$NEW_SCRIPT_LINTS
ALL_NEW_LINTS+=$(cat output.txt)
fi
done
if [ -n "${ALL_NEW_LINTS}" ]; then
echo -e "${ALL_NEW_LINTS}"
exit 1
fi
fi
exit 0