Skip to content

feat(blog): publish hybrid-project-bots #16

feat(blog): publish hybrid-project-bots

feat(blog): publish hybrid-project-bots #16

Workflow file for this run

name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
checks:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Check GTM snippet on all HTML pages
run: |
GTM_ID="G-MN16CB3V3T"
MISSING=()
while IFS= read -r file; do
# Skip backup directory
[[ "$file" == */backup/* ]] && continue
if ! grep -q "$GTM_ID" "$file"; then
MISSING+=("$file")
fi
done < <(find . -name "*.html" -type f)
if [ ${#MISSING[@]} -gt 0 ]; then
echo "::error::Google Tag Manager ($GTM_ID) missing from the following pages:"
for f in "${MISSING[@]}"; do
echo " ❌ $f"
done
echo ""
echo "Add this snippet to <head> after <meta charset=\"UTF-8\">:"
echo ""
echo ' <!-- Google tag (gtag.js) -->'
echo " <script async src=\"https://www.googletagmanager.com/gtag/js?id=$GTM_ID\"></script>"
echo ' <script>'
echo ' window.dataLayer = window.dataLayer || [];'
echo ' function gtag(){dataLayer.push(arguments);}'
echo " gtag('js', new Date());"
echo " gtag('config', '$GTM_ID');"
echo ' </script>'
exit 1
fi
echo "✅ All HTML pages have GTM ($GTM_ID)"
- name: Validate HTML structure
run: |
ERRORS=()
while IFS= read -r file; do
[[ "$file" == */backup/* ]] && continue
# Check for required meta tags
if ! grep -q '<meta charset' "$file"; then
ERRORS+=("$file: missing <meta charset>")
fi
if ! grep -q '<title>' "$file"; then
ERRORS+=("$file: missing <title>")
fi
if ! grep -q '<meta name="description"' "$file"; then
ERRORS+=("$file: missing <meta name=\"description\">")
fi
done < <(find . -name "*.html" -type f)
if [ ${#ERRORS[@]} -gt 0 ]; then
echo "::warning::HTML structure issues found:"
for e in "${ERRORS[@]}"; do
echo " ⚠️ $e"
done
# Warning only, don't fail
else
echo "✅ All HTML pages have required meta tags"
fi
- name: Validate blog posts.json
run: |
POSTS_JSON="./blog/posts.json"
if [ ! -f "$POSTS_JSON" ]; then
echo "::error::blog/posts.json not found!"
exit 1
fi
# Validate JSON syntax
if ! python3 -m json.tool "$POSTS_JSON" > /dev/null 2>&1; then
echo "::error::blog/posts.json has invalid JSON syntax"
exit 1
fi
ERRORS=()
# Check every post in posts.json has a matching HTML file
for url in $(python3 -c "import json; [print(p['url']) for p in json.load(open('$POSTS_JSON'))]"); do
filepath=".${url}"
if [ ! -f "$filepath" ]; then
ERRORS+=("Post in posts.json references missing file: $filepath")
fi
done
# Check every HTML file in blog/posts/ is listed in posts.json
LISTED_URLS=$(python3 -c "import json; [print(p['url']) for p in json.load(open('$POSTS_JSON'))]")
while IFS= read -r file; do
rel_path="/${file#./}"
if ! echo "$LISTED_URLS" | grep -qF "$rel_path"; then
ERRORS+=("Blog post not in posts.json: $rel_path")
fi
done < <(find ./blog/posts -name "*.html" -type f)
if [ ${#ERRORS[@]} -gt 0 ]; then
echo "::error::Blog manifest issues found:"
for e in "${ERRORS[@]}"; do
echo " ❌ $e"
done
echo ""
echo "Update blog/posts.json to match the actual blog post files."
exit 1
fi
POST_COUNT=$(python3 -c "import json; print(len(json.load(open('$POSTS_JSON'))))")
echo "✅ blog/posts.json is valid ($POST_COUNT posts, all files exist)"