Merge pull request #25 from codex-bot-andresmgsl/build/2-scaffold

ci: scaffold test and lint workspace
This commit is contained in:
Daniel Marin 2026-07-22 18:53:28 +01:00 committed by GitHub
commit 79cdbb81aa
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 150 additions and 0 deletions

21
.github/scripts/actionlint-all.sh vendored Executable file
View 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
View 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
View 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
View file

@ -0,0 +1 @@

1
docs/.gitkeep Normal file
View file

@ -0,0 +1 @@

1
lib/.gitkeep Normal file
View file

@ -0,0 +1 @@

36
test/harness.sh Normal file
View 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
View 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 ]