mirror of
https://github.com/qdrant/landing_page.git
synced 2026-09-26 14:38:30 +02:00
Fix CI.
This commit is contained in:
@@ -3,7 +3,6 @@ name: Check documentation prompts
|
|||||||
on:
|
on:
|
||||||
pull_request:
|
pull_request:
|
||||||
paths:
|
paths:
|
||||||
- 'qdrant-landing/content/documentation/headless/prompts/**'
|
|
||||||
- 'qdrant-landing/content/**/*.md'
|
- 'qdrant-landing/content/**/*.md'
|
||||||
- 'qdrant-landing/layouts/shortcodes/prompt.markdown.md'
|
- 'qdrant-landing/layouts/shortcodes/prompt.markdown.md'
|
||||||
- 'qdrant-landing/themes/qdrant-2024/layouts/shortcodes/prompt.html'
|
- 'qdrant-landing/themes/qdrant-2024/layouts/shortcodes/prompt.html'
|
||||||
@@ -16,22 +15,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Install Hugo
|
# Source checks only: no Hugo, no Dart Sass, no npm install. The rules
|
||||||
uses: peaceiris/actions-hugo@v3
|
# this guards are all visible in the source, so a full site build would
|
||||||
with:
|
# cost minutes on every docs PR to verify something that takes seconds.
|
||||||
hugo-version: '0.160.1'
|
|
||||||
extended: true
|
|
||||||
|
|
||||||
- name: Install Dart Sass
|
|
||||||
run: |
|
|
||||||
curl -sSL -o dart-sass.tar.gz \
|
|
||||||
https://github.com/sass/dart-sass/releases/download/1.70.0/dart-sass-1.70.0-linux-x64.tar.gz
|
|
||||||
tar -xzf dart-sass.tar.gz
|
|
||||||
echo "$PWD/dart-sass" >> "$GITHUB_PATH"
|
|
||||||
|
|
||||||
- name: Build site
|
|
||||||
working-directory: qdrant-landing
|
|
||||||
run: hugo --destination public
|
|
||||||
|
|
||||||
- name: Check prompts
|
- name: Check prompts
|
||||||
run: automation/prompts/check-prompts.sh
|
run: automation/prompts/check-prompts.sh
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ pages include them by id.
|
|||||||
2. Add `{{< prompt "<id>" >}}` to that page, near the top of the section it
|
2. Add `{{< prompt "<id>" >}}` to that page, near the top of the section it
|
||||||
relates to rather than at the bottom.
|
relates to rather than at the bottom.
|
||||||
|
|
||||||
3. Run `automation/prompts/check-prompts.sh` after a build.
|
3. Run `automation/prompts/check-prompts.sh`. It needs no build. Pass a built
|
||||||
|
site directory to also verify the real output, for example
|
||||||
|
`automation/prompts/check-prompts.sh qdrant-landing/public`.
|
||||||
|
|
||||||
## Writing one
|
## Writing one
|
||||||
|
|
||||||
@@ -68,4 +70,8 @@ prompt is never written as a plain fenced block on the page.
|
|||||||
who includes them, so a stale declaration would put a wrong link in the index,
|
who includes them, so a stale declaration would put a wrong link in the index,
|
||||||
and a prompt that is never included would still be listed.
|
and a prompt that is never included would still be listed.
|
||||||
|
|
||||||
`check-prompts.sh` guards both.
|
`check-prompts.sh` guards both, plus a third rule that keeps them equivalent:
|
||||||
|
the Markdown variant of the shortcode must never render the body. Rule one is
|
||||||
|
checked in the source rather than in the built output, because pasting a body
|
||||||
|
inline is a source-level mistake and catching it there means CI needs no site
|
||||||
|
build.
|
||||||
|
|||||||
@@ -1,25 +1,34 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Guards the two rules that keep documentation prompts working. Both fail
|
# Guards the rules that keep documentation prompts working. All of them fail
|
||||||
# silently otherwise, which is why they are checked rather than reviewed.
|
# silently otherwise, which is why they are checked rather than reviewed.
|
||||||
#
|
#
|
||||||
# 1. No prompt body reaches a built index.md. Those files are consumed by
|
# 1. No prompt body is written inline on a page. Prompt bodies must not reach
|
||||||
# agents, and a prompt is an instruction addressed to an agent, so it can
|
# a built index.md, because those files are consumed by agents and a prompt
|
||||||
# displace the question the agent was actually asked. Writing a prompt as a
|
# is an instruction addressed to an agent, so it can displace the question
|
||||||
# plain fenced block instead of using the shortcode is how this breaks.
|
# the agent was actually asked. The shortcode's Markdown variant drops the
|
||||||
# 2. Every prompt's declared `page:` really includes it. The prompt files live
|
# body, so the only way a body reaches index.md is an author pasting it as
|
||||||
|
# a fenced block instead of using the shortcode. That is a source-level
|
||||||
|
# mistake, so it is caught in the source.
|
||||||
|
# 2. The Markdown variant of the shortcode still drops the body. Rule 1 is
|
||||||
|
# only equivalent to "no body in index.md" while this holds.
|
||||||
|
# 3. Every prompt's declared `page:` really includes it. The prompt files live
|
||||||
# in one folder and cannot know who includes them, so the declaration is
|
# in one folder and cannot know who includes them, so the declaration is
|
||||||
# what the index trusts. This also catches a prompt that is written but
|
# what the index trusts. This also catches a prompt that is written but
|
||||||
# never used, which would otherwise appear in the index anyway.
|
# never used, which would otherwise appear in the index anyway.
|
||||||
#
|
#
|
||||||
# Usage: automation/prompts/check-prompts.sh [built-site-dir]
|
# These are all source checks, so no site build is needed and the run takes
|
||||||
# Default built-site-dir is qdrant-landing/public.
|
# seconds. Pass a built-site directory to additionally verify the real output:
|
||||||
|
#
|
||||||
|
# automation/prompts/check-prompts.sh # source checks only
|
||||||
|
# automation/prompts/check-prompts.sh qdrant-landing/public # and the build
|
||||||
|
|
||||||
set -Eeuo pipefail
|
set -Eeuo pipefail
|
||||||
|
|
||||||
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
||||||
public_dir="${1:-$repo_root/qdrant-landing/public}"
|
public_dir="${1:-}"
|
||||||
prompts_dir="$repo_root/qdrant-landing/content/documentation/headless/prompts"
|
prompts_dir="$repo_root/qdrant-landing/content/documentation/headless/prompts"
|
||||||
content_dir="$repo_root/qdrant-landing/content"
|
content_dir="$repo_root/qdrant-landing/content"
|
||||||
|
md_shortcode="$repo_root/qdrant-landing/layouts/shortcodes/prompt.markdown.md"
|
||||||
|
|
||||||
failures=0
|
failures=0
|
||||||
|
|
||||||
@@ -33,23 +42,23 @@ if [[ ! -d "$prompts_dir" ]]; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ ! -d "$public_dir" ]]; then
|
# --- rule 2: the Markdown variant must not render the prompt body ---
|
||||||
fail "built site not found at $public_dir (run hugo first, or pass the directory)"
|
if [[ ! -f "$md_shortcode" ]]; then
|
||||||
exit 1
|
fail "missing $md_shortcode: without it, prompt bodies reach the agent-facing Markdown"
|
||||||
|
elif grep -qE '\.(RawContent|Content|Inner)\b' "$md_shortcode"; then
|
||||||
|
fail "$md_shortcode renders the prompt body; it must emit only the skill pointer"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
prompt_files=("$prompts_dir"/*.md)
|
|
||||||
checked=0
|
checked=0
|
||||||
|
|
||||||
for file in "${prompt_files[@]}"; do
|
for file in "$prompts_dir"/*.md; do
|
||||||
id="$(basename "$file" .md)"
|
id="$(basename "$file" .md)"
|
||||||
[[ "$id" == "_index" ]] && continue
|
[[ "$id" == "_index" ]] && continue
|
||||||
checked=$((checked + 1))
|
checked=$((checked + 1))
|
||||||
|
|
||||||
# --- rule 1: the body must not appear in any built index.md ---
|
# First non-empty body line, used as the probe. Front matter is delimited by
|
||||||
# Use the first non-empty body line as the probe. Front matter is delimited
|
# the first two '---' lines.
|
||||||
# by the first two '---' lines.
|
|
||||||
probe="$(awk '
|
probe="$(awk '
|
||||||
/^---[[:space:]]*$/ { d++; next }
|
/^---[[:space:]]*$/ { d++; next }
|
||||||
d >= 2 && NF { print; exit }
|
d >= 2 && NF { print; exit }
|
||||||
@@ -60,13 +69,15 @@ for file in "${prompt_files[@]}"; do
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if hits="$(grep -rlF "$probe" --include='index.md' "$public_dir" 2>/dev/null)" && [[ -n "$hits" ]]; then
|
# --- rule 1: the body must not appear inline anywhere in the content tree ---
|
||||||
fail "$id: prompt body reached the agent-facing Markdown output:"
|
if hits="$(grep -rlF "$probe" --include='*.md' "$content_dir" 2>/dev/null \
|
||||||
|
| grep -v "^$prompts_dir/" || true)" && [[ -n "$hits" ]]; then
|
||||||
|
fail "$id: prompt body is written inline instead of using the shortcode:"
|
||||||
printf ' %s\n' $hits >&2
|
printf ' %s\n' $hits >&2
|
||||||
printf ' Use {{< prompt "%s" >}} rather than a fenced block.\n' "$id" >&2
|
printf ' Replace it with {{< prompt "%s" >}}\n' "$id" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# --- rule 2: the declared page must include the shortcode ---
|
# --- rule 3: the declared page must include the shortcode ---
|
||||||
page="$(awk -F': *' '
|
page="$(awk -F': *' '
|
||||||
/^---[[:space:]]*$/ { d++; if (d >= 2) exit; next }
|
/^---[[:space:]]*$/ { d++; if (d >= 2) exit; next }
|
||||||
d == 1 && $1 == "page" { print $2; exit }
|
d == 1 && $1 == "page" { print $2; exit }
|
||||||
@@ -77,7 +88,6 @@ for file in "${prompt_files[@]}"; do
|
|||||||
continue
|
continue
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# /documentation/foo/bar/ -> content/documentation/foo/bar.md or .../bar/_index.md
|
|
||||||
rel="${page#/}"
|
rel="${page#/}"
|
||||||
rel="${rel%/}"
|
rel="${rel%/}"
|
||||||
src=""
|
src=""
|
||||||
@@ -94,6 +104,18 @@ for file in "${prompt_files[@]}"; do
|
|||||||
fail "$id: declared page $page does not include it"
|
fail "$id: declared page $page does not include it"
|
||||||
printf ' Expected {{< prompt "%s" >}} in %s\n' "$id" "${src#"$repo_root"/}" >&2
|
printf ' Expected {{< prompt "%s" >}} in %s\n' "$id" "${src#"$repo_root"/}" >&2
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# --- optional: verify the real built output when a build is available ---
|
||||||
|
if [[ -n "$public_dir" ]]; then
|
||||||
|
if [[ ! -d "$public_dir" ]]; then
|
||||||
|
fail "built site not found at $public_dir"
|
||||||
|
public_dir=""
|
||||||
|
elif built="$(grep -rlF "$probe" --include='index.md' "$public_dir" 2>/dev/null || true)" \
|
||||||
|
&& [[ -n "$built" ]]; then
|
||||||
|
fail "$id: prompt body reached the agent-facing Markdown output:"
|
||||||
|
printf ' %s\n' $built >&2
|
||||||
|
fi
|
||||||
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
if (( failures > 0 )); then
|
if (( failures > 0 )); then
|
||||||
@@ -101,4 +123,8 @@ if (( failures > 0 )); then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf 'Prompt checks passed: %d prompt(s).\n' "$checked"
|
if [[ -n "$public_dir" ]]; then
|
||||||
|
printf 'Prompt checks passed (source and build): %d prompt(s).\n' "$checked"
|
||||||
|
else
|
||||||
|
printf 'Prompt checks passed: %d prompt(s).\n' "$checked"
|
||||||
|
fi
|
||||||
|
|||||||
Reference in New Issue
Block a user