forked from heavy-duty/ceremony
Merge pull request #25 from codex-bot-andresmgsl/build/2-scaffold
ci: scaffold test and lint workspace
This commit is contained in:
commit
79cdbb81aa
8 changed files with 150 additions and 0 deletions
21
.github/scripts/actionlint-all.sh
vendored
Executable file
21
.github/scripts/actionlint-all.sh
vendored
Executable file
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
cd "$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
mapfile -t files < <(
|
||||||
|
{
|
||||||
|
git ls-files '.github/workflows/*.yml'
|
||||||
|
git ls-files 'actions/*/action.yml'
|
||||||
|
} | sort -u
|
||||||
|
)
|
||||||
|
|
||||||
|
[ "${#files[@]}" -gt 0 ] || {
|
||||||
|
echo "actionlint-all: found no workflow or action files — the sweep is broken" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
printf 'actionlint: linting %d files\n' "${#files[@]}"
|
||||||
|
printf ' %s\n' "${files[@]}"
|
||||||
|
actionlint "${files[@]}"
|
||||||
|
|
||||||
32
.github/scripts/shellcheck-all.sh
vendored
Executable file
32
.github/scripts/shellcheck-all.sh
vendored
Executable file
|
|
@ -0,0 +1,32 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# A glob can quietly stop guarding when a script moves under a dot-directory
|
||||||
|
# or loses its extension. Derive the lint set from the tracked tree instead,
|
||||||
|
# following cast#118's fix, and print it so a shrinking sweep is visible.
|
||||||
|
cd "$(git rev-parse --show-toplevel)"
|
||||||
|
|
||||||
|
mapfile -t files < <(
|
||||||
|
{
|
||||||
|
git ls-files '*.sh'
|
||||||
|
git ls-files | while IFS= read -r file; do
|
||||||
|
case "$file" in *.sh) continue ;; esac
|
||||||
|
[ -f "$file" ] || continue
|
||||||
|
IFS= read -r line <"$file" || [ -n "$line" ] || continue
|
||||||
|
case "$line" in '#!'*) ;; *) continue ;; esac
|
||||||
|
interpreter="${line#\#!}"
|
||||||
|
interpreter="${interpreter%% -*}"
|
||||||
|
interpreter="${interpreter##*[ /]}"
|
||||||
|
case "$interpreter" in sh | bash | dash | ksh) printf '%s\n' "$file" ;; esac
|
||||||
|
done
|
||||||
|
} | sort -u
|
||||||
|
)
|
||||||
|
|
||||||
|
[ "${#files[@]}" -gt 0 ] || {
|
||||||
|
echo "shellcheck-all: found no shell scripts — the sweep is broken" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
printf 'shellcheck: linting %d tracked scripts\n' "${#files[@]}"
|
||||||
|
printf ' %s\n' "${files[@]}"
|
||||||
|
shellcheck -x "${files[@]}"
|
||||||
31
.github/workflows/ci.yml
vendored
Normal file
31
.github/workflows/ci.yml
vendored
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
name: CI
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- name: Shellcheck
|
||||||
|
run: bash .github/scripts/shellcheck-all.sh
|
||||||
|
- name: Install actionlint
|
||||||
|
env:
|
||||||
|
ACTIONLINT_VERSION: 1.7.12
|
||||||
|
run: |
|
||||||
|
curl -fsSLo actionlint.tar.gz \
|
||||||
|
"https://github.com/rhysd/actionlint/releases/download/v${ACTIONLINT_VERSION}/actionlint_${ACTIONLINT_VERSION}_linux_amd64.tar.gz"
|
||||||
|
tar -xzf actionlint.tar.gz actionlint
|
||||||
|
sudo install actionlint /usr/local/bin/actionlint
|
||||||
|
- name: Actionlint
|
||||||
|
run: bash .github/scripts/actionlint-all.sh
|
||||||
|
- name: Tests
|
||||||
|
run: bash test/run.sh
|
||||||
1
actions/.gitkeep
Normal file
1
actions/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
1
docs/.gitkeep
Normal file
1
docs/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
1
lib/.gitkeep
Normal file
1
lib/.gitkeep
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
|
||||||
36
test/harness.sh
Normal file
36
test/harness.sh
Normal file
|
|
@ -0,0 +1,36 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
# Sourced assertion helpers. Tests deliberately use set -u, not set -e:
|
||||||
|
# failing commands are behavior for the harness to inspect.
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
|
||||||
|
# check <desc> <want_exit> <want_substr> <cmd...>
|
||||||
|
check() {
|
||||||
|
local desc="$1" want="$2" substring="$3"
|
||||||
|
shift 3
|
||||||
|
local output rc
|
||||||
|
|
||||||
|
output="$("$@" 2>&1)"
|
||||||
|
rc=$?
|
||||||
|
if [ "$rc" -ne "$want" ]; then
|
||||||
|
echo "FAIL: $desc — exit $rc, wanted $want"
|
||||||
|
printf '%s\n' "$output" | sed 's/^/ /'
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ -n "$substring" ] && ! printf '%s' "$output" | grep -qF -e "$substring"; then
|
||||||
|
echo "FAIL: $desc — output missing '$substring'"
|
||||||
|
printf '%s\n' "$output" | sed 's/^/ /'
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo "ok: $desc"
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
summary() {
|
||||||
|
printf '%d passed, %d failed\n' "$PASS" "$FAIL"
|
||||||
|
[ "$FAIL" -eq 0 ]
|
||||||
|
}
|
||||||
|
|
||||||
27
test/run.sh
Executable file
27
test/run.sh
Executable file
|
|
@ -0,0 +1,27 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||||
|
shopt -s nullglob
|
||||||
|
tests=("$ROOT"/test/*.test.sh)
|
||||||
|
|
||||||
|
printf 'test: discovered %d test files\n' "${#tests[@]}"
|
||||||
|
if [ "${#tests[@]}" -eq 0 ]; then
|
||||||
|
echo "test: 0 tests — nothing to run"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
passed=0
|
||||||
|
failed=0
|
||||||
|
for test_file in "${tests[@]}"; do
|
||||||
|
printf '\n==> %s\n' "${test_file#"$ROOT"/}"
|
||||||
|
if bash "$test_file"; then
|
||||||
|
passed=$((passed + 1))
|
||||||
|
else
|
||||||
|
failed=$((failed + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
printf '\ntest files: %d passed, %d failed\n' "$passed" "$failed"
|
||||||
|
[ "$failed" -eq 0 ]
|
||||||
|
|
||||||
Loading…
Reference in a new issue