Skip to content

generate-podcast

generate-podcast #397

name: generate-podcast
on:
workflow_dispatch:
inputs:
debug:
description: 'Run in debug mode'
required: false
default: 'false'
type: boolean
voice_service:
description: 'Voice service to use'
required: false
default: 'openai'
type: choice
options:
- openai
- elevenlabs
skip_publish:
description: 'Skip publishing to podcast host'
required: false
default: 'true'
type: boolean
video:
description: 'Generate YouTube video'
required: false
default: 'false'
type: boolean
schedule:
- cron: '30 10 * * *' # 6:30am EST daily
permissions:
contents: read
actions: write # for caching
env:
NODE_VERSION: 23.6.0
PNPM_VERSION: 9.15.4
COVERED_STORIES_CACHE_KEY: ${{ github.ref }}-covered-stories
jobs:
podcast:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
# https://github.com/actions/virtual-environments/issues/1187
- name: tune linux network
run: sudo ethtool -K eth0 tx off rx off
- name: Install Puppeteer dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
ca-certificates fonts-liberation libasound2t64 libatk-bridge2.0-0 \
libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 \
libfontconfig1 libgbm1 libgcc-s1 libglib2.0-0 libgtk-3-0t64 \
libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 \
libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \
libxss1 libxtst6 lsb-release wget xdg-utils
- name: Setup FFmpeg
# Forked this PR: https://github.com/federicocarboni/setup-ffmpeg/pull/23
uses: denolfe/setup-ffmpeg@retries
- name: Node setup
uses: ./.github/actions/setup
with:
node-version: ${{ env.NODE_VERSION }}
pnpm-version: ${{ env.PNPM_VERSION }}
pnpm-install-cache-key: pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
- name: Create cache directory
run: mkdir ./cache
# Restore cache from cache/covered-stories
- name: Restore covered-stories
id: cache-restore
uses: actions/cache/restore@v4
with:
path: ./cache/covered-stories
key: ${{ env.COVERED_STORIES_CACHE_KEY }}
- name: Generate podcast
run: |
echo "skip_publish input: '$SKIP_PUBLISH'"
echo "video input: '$VIDEO'"
ARGS=""
if [ "$SKIP_PUBLISH" = "true" ]; then
ARGS="--no-publish"
fi
if [ "$VIDEO" = "true" ]; then
ARGS="$ARGS --video"
fi
echo "ARGS: '$ARGS'"
pnpm start -- $ARGS
env:
SKIP_PUBLISH: ${{ github.event.inputs.skip_publish }}
VIDEO: ${{ github.event.inputs.video }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ELEVEN_LABS_API_KEY: ${{ secrets.ELEVEN_LABS_API_KEY }}
DEBUG: ${{ github.event.inputs.debug }}
# Use `elevenlabs` on main, else `openai`
VOICE_SERVICE: ${{ github.event.inputs.voice_service || (github.ref == 'refs/heads/main' && 'elevenlabs' || 'openai') }}
TRANSISTOR_API_KEY: ${{ secrets.TRANSISTOR_API_KEY }}
- uses: actions/upload-artifact@v4
if: always()
with:
name: output-and-cache
path: |
output
cache
retention-days: 7
- name: Delete Previous Cache
if: ${{ steps.cache-restore.outputs.cache-hit }}
continue-on-error: true
run: |
gh extension install actions/gh-actions-cache
gh actions-cache delete "${{ env.COVERED_STORIES_CACHE_KEY }}" --confirm
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Cache cache/covered-stories for next run
- name: Cache covered-stories
uses: actions/cache/save@v4
with:
path: ./cache/covered-stories
key: ${{ env.COVERED_STORIES_CACHE_KEY }}
- name: Log covered-stories, show-notes, transcript
run: |
set -ex
cat cache/covered-stories
cat output/*.txt