Skip to content
Merged
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
140 changes: 140 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
---
name: ScreenKit Episode
description: Export a screencast episode using Docker
inputs:
episode:
description: "Episode number (e.g. 001)"
required: true
tts_preset:
description: "TTS preset name"
default: ""
required: false
tts_api_key:
description: "TTS API key"
required: false
overwrite:
description: "Regenerate files"
default: "false"
required: false
match:
description: "Match pattern for segments (e.g. 001)"
default: ""
required: false
github_token:
description: "GitHub token for cache operations"
required: true
retention:
description: "Retention days for artifacts"
default: 2

runs:
using: composite
steps:
- name: Generate cache keys
shell: bash
run: |
VOICEOVER_HASH=$(find episodes/${{ inputs.episode }}-*/scripts/*.txt -type f 2>/dev/null | sort | xargs sha256sum 2>/dev/null | sha256sum | cut -d' ' -f1 || echo "none")
CONTENT_HASH=$(find episodes/${{ inputs.episode }}-*/*/*.* -type f 2>/dev/null | sort | xargs sha256sum 2>/dev/null | sha256sum | cut -d' ' -f1 || echo "none")

echo "VOICEOVER_CACHE_KEY=episode-voiceover-${{ inputs.episode }}-${VOICEOVER_HASH}" >> $GITHUB_ENV
echo "VOICEOVER_RESTORE_KEY=episode-voiceover-${{ inputs.episode }}-" >> $GITHUB_ENV
echo "VIDEO_CACHE_KEY=episode-${{ inputs.episode }}-${CONTENT_HASH}" >> $GITHUB_ENV
echo "VIDEO_RESTORE_KEY=episode-${{ inputs.episode }}-" >> $GITHUB_ENV

- name: Find episode dir
shell: bash
run: |
EPISODE_DIR=$(ls -1d episodes/${{ inputs.episode }}-* | head -n 1)
echo "EPISODE_DIR=$EPISODE_DIR" >> $GITHUB_ENV

if [[ ! -d "$EPISODE_DIR" ]]; then
echo "Episode directory not found!"
echo "Available episodes:"
ls -1 episodes
exit 1
fi

- name: Restore episode voice cache
id: cache-voice
uses: actions/cache/restore@v4
with:
path: episodes/${{ inputs.episode }}-*/voiceovers
key: ${{ env.VOICEOVER_CACHE_KEY }}
restore-keys: ${{ env.VOICEOVER_RESTORE_KEY }}
enableCrossOsArchive: true

- name: Restore videos cache
id: cache-videos
uses: actions/cache/restore@v4
with:
path: output/${{ inputs.episode }}-*/videos/*.mp4
key: ${{ env.VIDEO_CACHE_KEY }}
restore-keys: ${{ env.VIDEO_RESTORE_KEY }}
enableCrossOsArchive: true

- name: Export Episode
shell: bash
id: screenkit
run: |
set -e
docker run \
--rm \
--cap-add=SYS_ADMIN \
--shm-size=2g \
--security-opt seccomp=unconfined \
-v ${{ github.workspace }}:/source \
fnando/screenkit:latest \
episode export \
--dir="${{ env.EPISODE_DIR }}" \
${{ inputs.match != '' && format('--match {0}', inputs.match) || '' }} \
${{ inputs.overwrite == 'true' && '--overwrite' || '--no-overwrite' }} \
${{ inputs.tts_preset != '' && format('--tts-preset {0}', inputs.tts_preset) || '' }} \
${{ inputs.tts_api_key != '' && format('--tts-api-key {0}', inputs.tts_api_key) || '' }}
echo "result=true" >> $GITHUB_OUTPUT

- name: Delete voice cache
if: steps.screenkit.outputs.result == 'true'
shell: bash
run: gh cache delete "${{ env.VOICEOVER_CACHE_KEY }}" || true
env:
GH_TOKEN: ${{ inputs.github_token }}

- name: Delete videos cache
if: steps.screenkit.outputs.result == 'true'
shell: bash
run: gh cache delete "${{ env.VIDEO_CACHE_KEY }}" || true
env:
GH_TOKEN: ${{ inputs.github_token }}

- name: List cache entries
shell: bash
run: |
echo "= Voiceover Cache ="
ls -la episodes/${{ inputs.episode }}-*/voiceovers || true
echo
echo "= Videos Cache ="
ls -la output/${{ inputs.episode }}-*/videos || true

- name: Save episode voiceover cache
if: steps.screenkit.outputs.result == 'true'
uses: actions/cache/save@v4
with:
path: episodes/${{ inputs.episode }}-*/voiceovers
key: ${{ env.VOICEOVER_CACHE_KEY }}
enableCrossOsArchive: true

- name: Save video recordings cache
if: steps.screenkit.outputs.result == 'true'
uses: actions/cache/save@v4
with:
path: output/${{ inputs.episode }}-*/videos/*.mp4
key: ${{ env.VIDEO_CACHE_KEY }}
enableCrossOsArchive: true

- name: Upload output artifacts
uses: actions/upload-artifact@v4
if: always()
with:
name: output
path: output
retention-days: ${{ inputs.retention }}
1 change: 1 addition & 0 deletions lib/screenkit/generators/project.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ def create_project_dir
def copy_files
copy_file "screenkit.yml"
directory "resources", exclude_pattern: /DS_Store/
directory ".github", exclude_pattern: /DS_Store/
end

def bundle_install
Expand Down
48 changes: 48 additions & 0 deletions lib/screenkit/generators/project/.github/screenkit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
name: Screenkit

on:
workflow_dispatch:
inputs:
episode:
type: string
description: "Episode number (e.g. 001)"
required: true
tts_preset:
description: "TTS preset name"
default: ""
type: choice
options:
- ""
- say
- espeak
- eleven_labs
- eleven_labs_mp3_192k
match:
type: string
description: "Match pattern for segments (e.g. 001)"
default: ""
overwrite:
type: boolean
description: "Regenerate files"

jobs:
screenkit:
runs-on: ubuntu-latest
permissions:
contents: read
actions: write

steps:
- name: Checkout repository
uses: actions/checkout@v3

- name: Run Screenkit
uses: fnando/screenkit@v1
with:
episode: ${{ github.event.inputs.episode }}
tts_preset: ${{ github.event.inputs.tts_preset }}
tts_api_key: ${{ secrets.TTS_API_KEY }}
overwrite: ${{ github.event.inputs.overwrite }}
match: ${{ github.event.inputs.match }}
github_token: ${{ secrets.GITHUB_TOKEN }}