Skip to content
Closed
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
130 changes: 130 additions & 0 deletions .github/workflows/howto.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
name: How-To docs

# Runs on every pull request (open + each push) and on manual dispatch.
# It stands up a throwaway AudioMuse-AI stack (prebuilt image + empty Postgres +
# Redis), drives a headless browser over every page with all data mocked in the
# browser, renders the version-stamped howto.md, validates it, and uploads the
# whole docs/howto/<version>/ folder as a build artifact for review.
#
# It does NOT commit anything and never touches main: you download the artifact,
# and if you like the result you commit it yourself.
#
# The version (and therefore the docs/howto/<version> folder, with the leading
# "v" stripped) is read from APP_VERSION in config.py — not from any git tag.

on:
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:
inputs:
image:
description: 'Override the app image (default ghcr.io/neptunehub/audiomuse-ai:<version>, falls back to :latest)'
required: false

permissions:
contents: write
packages: read

jobs:
capture:
runs-on: ubuntu-latest
steps:
- name: Checkout (PR head branch, so refreshed docs can be pushed back)
uses: actions/checkout@v4
with:
ref: ${{ github.head_ref || github.ref_name }}
fetch-depth: 0

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'

- name: Resolve version from config.py
id: ver
run: |
OUT=$(python docs/howto/_tooling/_version.py)
V=$(echo "$OUT" | awk '{print $1}')
NUM=$(echo "$OUT" | awk '{print $2}')
echo "version=$V" >> "$GITHUB_OUTPUT"
echo "num=$NUM" >> "$GITHUB_OUTPUT"
echo "config.py APP_VERSION: $V -> docs/howto/$NUM"

- name: Pick app image (version tag, else latest)
id: img
run: |
OVERRIDE="${{ github.event.inputs.image }}"
if [ -n "$OVERRIDE" ]; then
IMG="$OVERRIDE"
else
IMG="ghcr.io/neptunehub/audiomuse-ai:${{ steps.ver.outputs.version }}"
if ! docker manifest inspect "$IMG" >/dev/null 2>&1; then
echo "::warning::$IMG not found, falling back to :latest"
IMG="ghcr.io/neptunehub/audiomuse-ai:latest"
fi
fi
echo "image=$IMG" >> "$GITHUB_OUTPUT"
echo "Using image: $IMG"

- name: Start app stack
env:
HOWTO_IMAGE: ${{ steps.img.outputs.image }}
run: docker compose -f docs/howto/_tooling/docker-compose.howto.yml up -d

- name: Wait for /api/health
run: |
for i in $(seq 1 60); do
if curl -fsS http://localhost:8000/api/health >/dev/null 2>&1; then
echo "App is up after ${i} tries."
exit 0
fi
sleep 5
done
echo "App did not become healthy in time."
docker compose -f docs/howto/_tooling/docker-compose.howto.yml logs --tail=200 flask
exit 1

- name: Install Playwright + Chromium
run: |
pip install -r docs/howto/_tooling/requirements.txt
python -m playwright install --with-deps chromium

- name: Capture screenshots (all data mocked in the browser)
run: |
python docs/howto/_tooling/howto_capture.py \
--base-url http://localhost:8000 \
--user admin --password adminpass \
--mock-all --browser-channel ""

- name: Render + validate howto.md
run: |
python docs/howto/_tooling/render_howto.py
python docs/howto/_tooling/validate_howto.py

# Push the regenerated docs back to the PR branch (never main). Authenticated
# with GITHUB_TOKEN, so this push does NOT trigger another workflow run.
# Only commits when something actually changed.
- name: Commit refreshed docs to the PR branch
if: ${{ github.event_name == 'pull_request' }}
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add docs/howto/${{ steps.ver.outputs.num }}
if git diff --cached --quiet; then
echo "No documentation changes to commit."
else
git commit -m "docs(howto): refresh guide for ${{ steps.ver.outputs.version }}"
git push origin "HEAD:${{ github.head_ref }}"
fi

- name: Tear down stack
if: ${{ always() }}
run: docker compose -f docs/howto/_tooling/docker-compose.howto.yml down -v

- name: Upload how-to bundle for review
if: ${{ always() }}
uses: actions/upload-artifact@v4
with:
name: howto-${{ steps.ver.outputs.num }}
path: docs/howto/${{ steps.ver.outputs.num }}/
if-no-files-found: error
2 changes: 1 addition & 1 deletion config.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def _compute_headers():


# --- General Constants (Read from Environment Variables where applicable) ---
APP_VERSION = "v2.1.4"
APP_VERSION = "v2.1.5"
MAX_DISTANCE = float(os.environ.get("MAX_DISTANCE", "0.5"))
MAX_SONGS_PER_CLUSTER = int(os.environ.get("MAX_SONGS_PER_CLUSTER", "0"))
MAX_SONGS_PER_ARTIST = int(os.getenv("MAX_SONGS_PER_ARTIST", "3")) # Max songs per artist in similarity results and clustering
Expand Down
Loading