71 lines
3.2 KiB
YAML
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
|