process: keep the original run.log when a re-run renders nothing; dispatch input to override the voice URL (testing); drop netcheck

This commit is contained in:
Audiobook Producer
2026-10-18 01:50:11 -05:00
parent 153153010e
commit 9cba035adc
4 changed files with 13 additions and 24 deletions
+5 -1
View File
@@ -12,6 +12,10 @@ on:
description: 'PDF path inside the repo (empty = every PDF waiting in _incoming/)'
required: false
default: 'books/clark-glenn/the-man-who-tapped-the-secrets-of-the-universe/The Man Who Tapped the Secrets of the Universe - by Glenn Clark (Walter Russell).pdf'
voice_endpoint:
description: 'Testing only: use this voice URL instead of the default (for example to prove a failed voice run commits nothing)'
required: false
default: ''
dry_run:
description: 'true = text stages only, voice reachability check, push-permission test, commit nothing'
type: boolean
@@ -31,7 +35,7 @@ jobs:
# The commit-back commit carries [skip ci] and removes the PDF from _incoming/, so it cannot start another run.
if: ${{ !contains(github.event.head_commit.message, '[skip ci]') }}
env:
AUDIOBOOK_VOICE_ENDPOINT: ${{ vars.AUDIOBOOK_VOICE_ENDPOINT || 'http://192.168.1.202:8090/tts' }}
AUDIOBOOK_VOICE_ENDPOINT: ${{ (github.event_name == 'workflow_dispatch' && inputs.voice_endpoint) || vars.AUDIOBOOK_VOICE_ENDPOINT || 'http://192.168.1.202:8090/tts' }}
AUDIOBOOK_WORK_DIR: /tmp/audiobook-work
AUDIOBOOK_REQUIRE_OCR: '1'
BRANCH: ${{ github.ref_name }}
-21
View File
@@ -1,21 +0,0 @@
# Diagnostic only: what can a job container reach? Run by hand (Run workflow). Changes nothing.
name: netcheck
on:
workflow_dispatch:
jobs:
net:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- name: Network facts from inside the job container
run: |
set +e
echo "--- identity"; hostname; cat /etc/resolv.conf
echo "--- addr/route/mtu"; (ip addr || cat /proc/net/dev) 2>&1 | head -30; ip route 2>&1 | head
echo "--- dns gitea"; getent hosts gitea.vps1.afterthedemo.com
echo "--- server url: ${{ github.server_url }}"
echo "--- curl gitea healthz"; curl -sS -m 20 -o /dev/null -w "http=%{http_code} connect=%{time_connect}s total=%{time_total}s ip=%{remote_ip}\n" https://gitea.vps1.afterthedemo.com/api/healthz
echo "--- curl gitea repo page"; curl -sS -m 30 -o /dev/null -w "http=%{http_code} size=%{size_download} total=%{time_total}s\n" https://gitea.vps1.afterthedemo.com/Ty_Tech/old-books
echo "--- git ls-remote (token)"; time git -c http.extraheader="AUTHORIZATION: basic $(printf 'x-access-token:%s' '${{ github.token }}' | base64 -w0)" ls-remote https://gitea.vps1.afterthedemo.com/Ty_Tech/old-books 2>&1 | head -5
echo "--- curl voice model-info"; curl -sS -m 20 -w "\nhttp=%{http_code} total=%{time_total}s\n" http://192.168.1.202:8090/api/model-info
echo "--- ping mtu probes to gitea"; for s in 1200 1400 1472; do curl -sS -m 15 -o /dev/null -w "post $s bytes: http=%{http_code}\n" -X POST --data-binary @<(head -c $s /dev/zero) https://gitea.vps1.afterthedemo.com/api/healthz; done
+6 -2
View File
@@ -193,6 +193,7 @@ def run_text_stages(cfg, pdf, title, author):
def run_audio_stages(cfg, book_dir, book, force):
"""Returns True if any audio was rendered."""
out_dir = settings.audio_dir(cfg, book_dir)
built = book.setdefault("audio_built", {})
todo = []
@@ -228,10 +229,12 @@ def run_audio_stages(cfg, book_dir, book, force):
print("voice model unloaded to free the GPU")
else:
print("nothing to render")
rendered = bool(todo)
step("ACX check")
rc = acx_check.run(cfg, [out_dir])
if rc != 0:
raise Failed("ACX check FAILED (see the table above); nothing should be committed")
return rendered
def process(cfg, pdf, dry_run=False, force=False, title=None, author=None, compare=None, result_file=None, compare_strict=False):
@@ -244,6 +247,7 @@ def process(cfg, pdf, dry_run=False, force=False, title=None, author=None, compa
real_out = sys.stdout
sys.stdout = Tee(real_out, log)
book_dir = None
rendered = False
try:
print("process %s%s" % (os.path.basename(pdf), " [DRY RUN: text stages only]" if dry_run else ""))
book_dir, book = run_text_stages(cfg, pdf, title, author)
@@ -269,7 +273,7 @@ def process(cfg, pdf, dry_run=False, force=False, title=None, author=None, compa
print("voice server reachable:", h)
else:
try:
run_audio_stages(cfg, book_dir, book, force)
rendered = run_audio_stages(cfg, book_dir, book, force)
except voice.VoiceError as e:
raise Failed("voice: %s" % e)
print("\nPROCESS OK: %s" % book_dir)
@@ -284,7 +288,7 @@ def process(cfg, pdf, dry_run=False, force=False, title=None, author=None, compa
rc = 1
finally:
sys.stdout = real_out
if rc == 0 and book_dir and not dry_run:
if rc == 0 and book_dir and not dry_run and rendered: # a re-run that renders nothing keeps the original log
out_dir = settings.audio_dir(cfg, book_dir)
os.makedirs(out_dir, exist_ok=True)
with open(os.path.join(out_dir, "run.log"), "w", encoding="utf-8") as f:
+2
View File
@@ -117,6 +117,7 @@ class ProcessTests(unittest.TestCase):
"book.json", "warnings.log", "LICENSE_STATUS.md"):
self.assertTrue(os.path.exists(os.path.join(b, rel)), rel)
self.assertIn("public domain", open(os.path.join(b, "LICENSE_STATUS.md")).read())
log_before = open(os.path.join(b, "audio", "run.log")).read()
mtimes = {n: os.path.getmtime(os.path.join(b, "audio", n)) for n in names if n.endswith(".mp3")}
posts = len(Stub.posts)
self.assertGreater(posts, 0)
@@ -125,6 +126,7 @@ class ProcessTests(unittest.TestCase):
self.assertEqual(rc, 0, out)
self.assertEqual(len(Stub.posts), posts)
self.assertIn("nothing to render", out)
self.assertEqual(log_before, open(os.path.join(b, "audio", "run.log")).read()) # original render log kept
self.assertEqual(mtimes, {n: os.path.getmtime(os.path.join(b, "audio", n)) for n in mtimes})
rc, out = run_process(self.cfg, self.pdf, force=True) # forced: renders again
self.assertEqual(rc, 0, out)