Skip to content
Open
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
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ jobs:
- test
- unused-media
- test-go-redirects
- validate-aliases
- dockerfile-lint
- validate-vendor
steps:
Expand Down
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,11 @@ RUN --mount=type=bind,src=pagefind.yml,target=pagefind.yml \
FROM scratch AS index
COPY --from=pagefind /pagefind .

# validate-aliases checks for circular aliases in content frontmatter
FROM alpine:${ALPINE_VERSION} AS validate-aliases
WORKDIR /test
RUN --mount=type=bind,target=. sh hack/test/validate_aliases

# test-go-redirects checks that the /go/ redirects are valid
FROM alpine:${ALPINE_VERSION} AS test-go-redirects
WORKDIR /work
Expand Down
8 changes: 7 additions & 1 deletion docker-bake.hcl
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ target "release" {
}

group "validate" {
targets = ["lint", "test", "unused-media", "test-go-redirects", "dockerfile-lint", "validate-vendor"]
targets = ["lint", "test", "unused-media", "test-go-redirects", "validate-aliases", "dockerfile-lint", "validate-vendor"]
}

target "test" {
Expand Down Expand Up @@ -76,6 +76,12 @@ target "test-go-redirects" {
provenance = false
}

target "validate-aliases" {
target = "validate-aliases"
output = ["type=cacheonly"]
provenance = false
}

target "dockerfile-lint" {
call = "check"
}
Expand Down
73 changes: 73 additions & 0 deletions hack/test/validate_aliases
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
#!/usr/bin/env sh
set -e

echo "Checking for circular aliases..."

ERRORS=$(mktemp)

find content -name "*.md" | sort | while read -r file; do
# Compute the canonical URL for this file based on hugo.yaml permalink config:
# manuals pages: /:sections[1:]/:slugorcontentbasename/ (strips "manuals")
# all other pages: standard Hugo URL
path="${file#content/}"

if echo "$path" | grep -q "^manuals/"; then
path="${path#manuals/}"
fi

if [ "$(basename "$path")" = "_index.md" ]; then
dir="$(dirname "$path")"
if [ "$dir" = "." ]; then
page_url="/"
else
page_url="/$dir/"
fi
else
page_url="/$(echo "$path" | sed 's/\.md$//')/"
fi

# Extract aliases from YAML frontmatter
aliases=$(awk '
BEGIN { fm=0; in_aliases=0 }
/^---$/ {
if (fm == 0) { fm=1; next }
else { exit }
}
fm && /^aliases: \[/ {
line = substr($0, index($0, "[") + 1)
gsub(/\].*/, "", line)
n = split(line, parts, ",")
for (i = 1; i <= n; i++) {
val = parts[i]
gsub(/^[ \t"'"'"']+|[ \t"'"'"']+$/, "", val)
if (val != "") print val
}
next
}
fm && /^aliases:/ { in_aliases=1; next }
fm && in_aliases && /^ - / { print substr($0, 5) }
Comment thread
craig-osterhout marked this conversation as resolved.
fm && in_aliases && /^[^ ]/ { in_aliases=0 }
' "$file")

set -f
while IFS= read -r alias; do
[ -z "$alias" ] && continue
# Normalize: ensure leading and trailing slash
alias=$(echo "$alias" | sed 's|/*$|/|; s|^/*|/|')
if [ "$alias" = "$page_url" ]; then
echo "Circular alias in $file: '$alias' resolves to the same URL as the page" >> "$ERRORS"
fi
done <<EOF
$aliases
EOF
set +f
done

if [ -s "$ERRORS" ]; then
cat "$ERRORS"
rm "$ERRORS"
exit 1
fi

rm "$ERRORS"
echo "No circular aliases found."
Loading