Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@ jobs:
- name: Check Terraform examples
run: terraform fmt -check -recursive examples

- name: Check Markdown links
run: bash scripts/check-markdown-links.sh

- name: Validate Terraform examples
run: bash scripts/check-examples.sh

- name: Test
run: go test -short -timeout=2m ./...

Expand Down
4 changes: 3 additions & 1 deletion docs/release.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ Use this checklist before publishing a Kernel Terraform provider version.

## Release Preconditions

- Work from a clean checkout of the repository's canonical post-merge branch after the PR stack is merged. The current default branch is `provider-repo-scaffold`; confirm with `gh repo view --json defaultBranchRef` before tagging.
- Work from a clean `main` checkout after the PR stack is merged.
- Run `bash scripts/check-docs.sh`.
- Run `bash scripts/check-markdown-links.sh`.
- Run `bash scripts/check-examples.sh`.
- Run `terraform fmt -check -recursive examples`.
- Run `go test -short -timeout=2m ./...`.
- Run `go vet ./...`.
Expand Down
49 changes: 49 additions & 0 deletions scripts/check-examples.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#!/usr/bin/env bash
set -euo pipefail

root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
workdir="$(mktemp -d "${TMPDIR:-/tmp}/kernel-tfexamples.XXXXXX")"

cleanup() {
rm -rf "$workdir"
}
trap cleanup EXIT

command -v terraform >/dev/null || {
echo "terraform is required to validate examples" >&2
exit 1
}

mkdir -p "$workdir/plugins"

cd "$root"
go build -o "$workdir/plugins/terraform-provider-kernel" ./cmd/terraform-provider-kernel

cat >"$workdir/terraformrc" <<EOF
provider_installation {
dev_overrides {
"kernel/kernel" = "$workdir/plugins"
}

direct {}
}
EOF

validated=0
while IFS= read -r example; do
echo "validating $example"
(
cd "$example"
TF_CLI_CONFIG_FILE="$workdir/terraformrc" CHECKPOINT_DISABLE=1 \
terraform validate -no-color
)
validated=$((validated + 1))
done < <(find examples -mindepth 1 -maxdepth 1 -type d -exec test -f '{}/main.tf' ';' -print | sort)
Comment thread
cursor[bot] marked this conversation as resolved.
Comment thread
cursor[bot] marked this conversation as resolved.

# Guard against a silent no-op: an empty examples tree (or a failed find)
# must not let the check pass without validating anything.
if [ "$validated" -eq 0 ]; then
echo "no example configurations found under examples/" >&2
exit 1
fi
echo "validated $validated example configurations"
58 changes: 58 additions & 0 deletions scripts/check-markdown-links.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env bash
set -euo pipefail

root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"

cd "$root"

command -v python3 >/dev/null || {
echo "python3 is required to check Markdown links" >&2
exit 1
}

python3 - <<'PY'
import pathlib
import re
import subprocess
import sys
import urllib.parse

root = pathlib.Path.cwd()
tracked_markdown = subprocess.check_output(["git", "ls-files", "*.md"], text=True)
files = [pathlib.Path(p) for p in tracked_markdown.splitlines()]
# Matches both links and images; a missing local image target is just as
# broken a reference as a missing link target.
link_re = re.compile(r"!?\[[^\]]*\]\(([^)]+)\)")
title_re = re.compile(r'^(\S+)\s+"[^"]*"$')
errors: list[str] = []

for path in files:
text = path.read_text(encoding="utf-8")
for match in link_re.finditer(text):
target = match.group(1).strip()
# Drop an optional quoted title: [text](path "title").
titled = title_re.match(target)
if titled:
target = titled.group(1)
if not target or target.startswith(("#", "http://", "https://", "mailto:")):
continue

target = target.split("#", 1)[0]
target = urllib.parse.unquote(target)
if not target:
continue

resolved = (root / path.parent / target).resolve()
try:
resolved.relative_to(root)
except ValueError:
errors.append(f"{path}: link leaves repository: {target}")
continue

if not resolved.exists():
errors.append(f"{path}: missing link target: {target}")
Comment thread
cursor[bot] marked this conversation as resolved.

if errors:
print("\n".join(errors), file=sys.stderr)
sys.exit(1)
PY