Generate AI Videos in Your CI/CD Pipeline with GitHub Actions
Every product launch needs a video. Every changelog deserves a walkthrough. Every marketing campaign runs on short-form content. But manually producing videos for every release is a bottleneck. What if your CI/CD pipeline could generate the video for you — automatically, on every deploy?
Why automate video generation in CI/CD?
Teams already automate tests, deployments, and notifications. Video is the missing piece. Here are three use cases where automated video generation pays for itself immediately:
Product launches
Trigger a video on every GitHub release. The script can reference the release name and changelog. By the time your release notes hit Twitter, the video is already rendered and ready to attach.
Changelog videos
Push to CHANGELOG.md and a video is generated automatically. Ship weekly update videos to your users without anyone opening a video editor.
Marketing at scale
Use matrix strategies to generate multiple variants — different actors, different subtitle styles, different scripts — in a single workflow run. A/B test video ads without a production team.
The GitHub Action
The agent-media GitHub Action is a reusable workflow that calls the agent-media API to generate a UGC video. It accepts a script, an optional actor, duration, and subtitle style. When sync: true is set, it polls until the video is ready and outputs the URL.
| Input | Default | Description |
|---|---|---|
| script | (required) | The video script text |
| actor_slug | random | Actor to use for the talking head |
| duration | 10 | Video duration in seconds |
| style | hormozi | Subtitle style (hormozi, karaoke, bold, tiktok, minimal) |
| sync | true | Wait for generation to complete |
The action outputs video_url and job_id so downstream steps can use the generated video — post it to Slack, attach it to a GitHub release, or upload it to your CDN.
Setup: 2 minutes
- 1Get an API key. Sign up at agent-media.ai and copy your API key from the dashboard.
- 2Add the secret. Go to your repo's Settings > Secrets and variables > Actions and add
AGENT_MEDIA_API_KEYas a repository secret. - 3Add the workflow. Create a workflow YAML file that references the reusable action. See the examples below.
Basic usage: video on every release
This workflow triggers on every GitHub release and generates a 10-second UGC video with the release name embedded in the script. The video URL is available in the workflow summary.
name: Generate Product Video
on:
release:
types: [published]
jobs:
video:
uses: agent-media/videoagent/.github/workflows/generate-video.yml@main
with:
script: "We just shipped ${{ github.event.release.name }}. Here is what changed and why you should update today."
actor_slug: random
duration: 10
style: hormozi
sync: true
secrets:
AGENT_MEDIA_API_KEY: ${{ secrets.AGENT_MEDIA_API_KEY }}That is the entire workflow. Push this file to your repo and every release automatically gets a video. The action handles API authentication, job submission, polling, and output extraction.
Changelog-driven videos
Want a video every time you update your changelog? This workflow watches for changes to CHANGELOG.md on the main branch, extracts the latest entry, and generates a video from it.
name: Changelog Video
on:
push:
branches: [main]
paths:
- 'CHANGELOG.md'
jobs:
read-changelog:
runs-on: ubuntu-latest
outputs:
entry: ${{ steps.parse.outputs.entry }}
steps:
- uses: actions/checkout@v4
- name: Extract latest changelog entry
id: parse
run: |
ENTRY=$(sed -n '/^## /,/^## /{ /^## /!p; }' CHANGELOG.md | head -20)
echo "entry=${ENTRY}" >> "$GITHUB_OUTPUT"
generate:
needs: read-changelog
uses: agent-media/videoagent/.github/workflows/generate-video.yml@main
with:
script: ${{ needs.read-changelog.outputs.entry }}
style: bold
duration: 15
sync: true
secrets:
AGENT_MEDIA_API_KEY: ${{ secrets.AGENT_MEDIA_API_KEY }}Advanced: matrix strategy for multiple variants
Need multiple versions of the same video for A/B testing? Use a GitHub Actions matrix strategy to generate variants in parallel — different actors, different subtitle styles, all from the same script.
name: Generate Video Variants
on:
workflow_dispatch:
inputs:
script:
description: "Video script"
required: true
jobs:
variants:
strategy:
matrix:
actor: [emma-casual, alex-studio, jordan-outdoor]
style: [hormozi, tiktok]
uses: agent-media/videoagent/.github/workflows/generate-video.yml@main
with:
script: ${{ inputs.script }}
actor_slug: ${{ matrix.actor }}
style: ${{ matrix.style }}
sync: true
secrets:
AGENT_MEDIA_API_KEY: ${{ secrets.AGENT_MEDIA_API_KEY }}This generates 6 video variants (3 actors x 2 styles) in parallel. Each variant runs as its own job, so they all execute concurrently. With a 10-second video taking roughly 60 seconds to render, you get all 6 variants in about a minute.
Under the hood: the API call
The GitHub Action wraps a single REST API call. If you want to integrate video generation into other CI/CD systems (GitLab CI, CircleCI, Jenkins), here is the raw API call:
curl -X POST https://api-v2-production-2f24.up.railway.app/v1/generate/ugc_video \
-H "Authorization: Bearer $AGENT_MEDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"script": "Your video script here",
"actor_slug": "random",
"duration": 10,
"subtitle_style": "hormozi"
}'The API returns a job ID immediately. Poll GET /v1/jobs/:job_id until the status is completed to get the video URL. The GitHub Action handles this polling loop automatically.
What teams are building with this
- *Release announcement videos generated on every GitHub release
- *Weekly changelog recap videos triggered by CHANGELOG.md updates
- *Onboarding videos regenerated when docs change
- *Marketing variant testing with matrix strategies across actors and styles
- *Automated social media content pipelines: generate, upload, post
- *Customer success videos personalized per account using workflow inputs
Add video generation to your pipeline
One secret, one workflow file, automated videos on every deploy.
uses: agent-media/videoagent/.github/workflows/generate-video.yml@main
with:
script: "Your script here"
secrets:
AGENT_MEDIA_API_KEY: ${{ secrets.AGENT_MEDIA_API_KEY }}