Files
old-books/.gitea/workflows/audiobook.yml
T

71 lines
3.2 KiB
YAML

# Drop a PDF in _incoming/ and commit it. This job turns it into a finished audiobook folder and commits that back.
# No bot is involved: every step is a deterministic script in _pipeline/.
name: audiobook
on:
push:
branches: [main, 'test/**'] # test/** lets the pipeline be proven on a branch without touching main
paths: ['_incoming/*.pdf'] # only a PDF landing in _incoming/ starts a run
workflow_dispatch:
inputs:
pdf:
description: 'PDF path inside the repo (empty = every PDF waiting in _incoming/; a dry run with nothing waiting uses the Clark book as a regression sample)'
required: false
default: ''
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
default: true
permissions:
contents: write
concurrency:
group: audiobook
cancel-in-progress: false # one book at a time; a second drop waits
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 720 # long books render for hours
# 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: ${{ (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 }}
DRY_RUN: ${{ github.event_name == 'workflow_dispatch' && inputs.dry_run || 'false' }}
PDF_INPUT: ${{ github.event_name == 'workflow_dispatch' && inputs.pdf || '' }}
steps:
- name: Check out the repository
timeout-minutes: 15 # a stalled fetch fails the run instead of hanging it for hours
uses: actions/checkout@v4
with:
fetch-depth: 100 # enough history to rebase onto a main that moved during a long render
filter: blob:none # do not download every book's audio and PDFs on every run
sparse-checkout: |
/_pipeline/
/_incoming/
/.gitea/
sparse-checkout-cone-mode: false
- name: Install tools (fresh container every run)
run: bash _pipeline/ci/install.sh
- name: Unit tests (dry runs only)
if: ${{ env.DRY_RUN == 'true' }}
run: |
.venv/bin/pip install -q --disable-pip-version-check reportlab pillow
.venv/bin/python -W ignore -m unittest discover -s _pipeline/tests 2>&1 | grep -v -E '^\s+(data|read) =' | tail -40
test "${PIPESTATUS[0]}" -eq 0
- name: Voice server reachable from this job
run: |
echo "voice endpoint: $AUDIOBOOK_VOICE_ENDPOINT"
base="${AUDIOBOOK_VOICE_ENDPOINT%/tts}"
curl -sS --max-time 20 "$base/api/model-info" && echo
- name: Process
run: bash _pipeline/ci/run.sh