Skip to content

fix(video-importer): harden packaging and upload diagnostics#9229

Open
tanflem wants to merge 3 commits into
tannerfleming/vmt-234-add-handling-for-burned-in-subtitles-in-video-importerfrom
tannerfleming/qa-476-investigate-and-fix-video-importer-upload-bug
Open

fix(video-importer): harden packaging and upload diagnostics#9229
tanflem wants to merge 3 commits into
tannerfleming/vmt-234-add-handling-for-burned-in-subtitles-in-video-importerfrom
tannerfleming/qa-476-investigate-and-fix-video-importer-upload-bug

Conversation

@tanflem
Copy link
Copy Markdown
Contributor

@tanflem tanflem commented May 19, 2026

Summary

Hardens the video importer packaging and runtime diagnostics on top of the burned-in subtitle branch.

What Changed

  • verifies R2 uploads by checking both the stored object and the public URL before treating a file as complete
  • requires Slack and Firebase email/password configuration at startup, with a Slack misconfiguration alert when non-Slack env is broken
  • removes JWT token env support from the importer and standardizes on Firebase email/password auth
  • adds focused importer tests plus a lightweight local fixture reset workflow that keeps generated media out of git

Verification

  • pnpm dlx nx run video-importer:test
  • pnpm dlx nx run video-importer:type-check
  • pnpm dlx nx run video-importer:lint
  • pnpm dlx nx run video-importer:package
  • packaged importer run against local fixture set: expected 3 successful / 3 failed
  • packaged dry-run startup failures for broken env overrides, including required Slack checks and Slack misconfiguration alerts

Summary by CodeRabbit

  • New Features

    • Slack integration is now mandatory for run summaries
    • Startup environment validation with detailed configuration error reporting
    • Enhanced upload verification against public URLs
  • Documentation

    • Added Video Importer Agent Guide documenting setup and requirements
    • Updated README clarifying Slack as required configuration
    • Added test fixtures documentation and reset script
  • Tests

    • Added unit tests for video importer module
    • Added startup validation tests

Review Change Stack

@linear
Copy link
Copy Markdown

linear Bot commented May 19, 2026

QA-476

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 19, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: b42a8661-26f8-451c-b630-57416af0db72

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

The PR enforces environment variable validation at startup, migrates GraphQL authentication from optional JWT to required Firebase tokens, adds public URL verification to R2 uploads, makes Slack integration mandatory with misconfiguration alerts, and provides test fixture infrastructure and documentation.

Changes

Video Importer Environment Validation and Upload Verification

Layer / File(s) Summary
Environment Contracts and Validation Schema
src/env.ts, src/types.ts, src/startupPreflight.ts
FIREBASE_EMAIL, FIREBASE_PASSWORD, SLACK_BOT_TOKEN, and SLACK_CHANNEL_ID are now required in env.server. A new startupPreflight module validates all required configuration using zod and exports checkStartupEnvironment to report missing or invalid variables. R2Asset gains optional fileName and originalFilename metadata fields.
Startup Preflight Validation
src/utils/startupPreflight.spec.ts
Test suite for checkStartupEnvironment verifies that valid environments pass, missing Slack/Firebase variables are caught, and invalid URLs are flagged with appropriate messages.
Firebase Authentication Migration
src/gql/graphqlClient.ts
GraphQL authentication is migrated from optional env.JWT_TOKEN to always using Firebase ID token via signInWithEmailAndPassword. A new getFirebaseAuthToken() helper caches the token with ~55-minute expiry and auto-refresh; GraphQL client reuse is keyed off the Firebase auth token instead of JWT.
R2 Upload Verification and Diagnostics
src/services/r2.ts
uploadToR2 now accepts publicUrl and performs two-step verification: private object check via verifyFileUpload, then public URL verification via new verifyPublicUrl (HEAD request timeout validation, content-length/type matching, ranged GET for non-empty content). New formatR2AssetDiagnostic formats optional R2Asset fields for error messages. uploadFileToR2Direct now requires contentLength and verifies both object and public URL before returning.
Media Processors with R2 Updates
src/importers/audiopreview.ts, src/importers/subtitle.ts, src/importers/video.ts, src/importers/video.spec.ts
Audio preview, subtitle, and video processors pass contentLength and publicUrl to R2 uploads and append formatR2AssetDiagnostic diagnostic info to failure messages. Comprehensive test suite for video processor covers filename parsing (normal and burned-in variants), successful end-to-end flow, and failure cases (blank languageId, missing file, metadata read error).
Slack Integration as Required Service
src/services/slack.ts
Slack credentials are now required; credential resolution throws instead of returning null/false on missing SLACK_BOT_TOKEN or SLACK_CHANNEL_ID. New postVideoImporterMisconfigurationAlert sends a Slack notification with up to 20 .env validation errors and hostname. Error column width increased from 60 to 120 characters. Slack message body construction refactored to use incoming text and blocks directly.
Main Entry Point and Startup Flow
src/video-importer.ts
main() now calls checkStartupEnvironment() at startup; on failure, logs errors, attempts Slack misconfiguration alert if Slack env vars present and notifications enabled, then exits with code 1. Processor module imports converted to parallel dynamic import() calls. Slack gating conditions updated from !options.noSlack to options.slack.
Documentation and Agent Guide
README.md, AGENTS.md
README updated to describe Slack as required and explain startup configuration error behavior, Slack misconfiguration alerts, and --no-slack usage for local diagnostics. New AGENTS.md documents importer purpose, setup, Nx targets, filename/import contracts, safety rules, packaging, testing, and quality gates.
Test Fixtures and Local Development Infrastructure
test-videos/.gitignore, test-videos/README.md, test-videos/reset-fixtures.sh
.gitignore excludes generated fixture media (*.mp4, *.srt, *.aac and .completed variants). New README explains fixture generation via reset-fixtures.sh, .completed restoration behavior, intentionally invalid fixtures, and guidance on --dry-run. Bash script creates MP4, subtitle, and invalid-format fixtures with helpers for restoration and validation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • Kneesal
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main objective of hardening R2 upload packaging and diagnostics, which is the core focus across multiple files including R2 verification logic, startup preflight checks, and improved error messaging.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch tannerfleming/qa-476-investigate-and-fix-video-importer-upload-bug

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 19, 2026

Warnings
⚠️ ❗ Big PR (794 changes)

(change count - 794): Pull Request size seems relatively large. If Pull Request contains multiple changes, split each into separate PR will helps faster, easier review.

Generated by 🚫 dangerJS against 9e68f3b

@tanflem tanflem self-assigned this May 19, 2026
@tanflem tanflem requested a review from Kneesal May 19, 2026 22:05
@tanflem
Copy link
Copy Markdown
Contributor Author

tanflem commented May 21, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
apps/video-importer/src/importers/video.spec.ts (2)

108-146: ⚡ Quick win

Add coverage for the behaviors actually changed in this PR.

The success test verifies counts but never asserts that the new publicUrl argument is forwarded to uploadToR2, and there is no test for the new failure branch where uploadToR2 rejects and the recorded failure message includes formatR2AssetDiagnostic(r2Asset) output ("R2 upload/public verification: …"). Those two behaviors are the core changes in video.ts for this PR and should be pinned by tests.

As per coding guidelines: "Add or update co-located *.spec.ts tests for parsing, validation, retry/status behavior, and import branching touched by a change".

Suggested additions
     assert.equal(uploadToR2Mock.mock.calls.length, 1)
+    const uploadArgs = uploadToR2Mock.mock.calls[0].arguments[0]
+    assert.equal(uploadArgs.publicUrl, 'https://cdn.example.com/video.mp4')
+    assert.equal(uploadArgs.uploadUrl, 'https://upload.example.com/video.mp4')
     assert.equal(requestMock.mock.calls.length, 1)
     assert.equal(markFileAsCompletedMock.mock.calls.length, 1)
   })
+
+  it('should record an upload/public-verification failure with diagnostic info when uploadToR2 rejects', async () => {
+    validateVideoAndEditionMock.mock.mockImplementation(async () => ({
+      editionId: 'edition-id'
+    }))
+    getVideoMetadataMock.mock.mockImplementation(async () => ({
+      durationMs: 10000,
+      duration: 10,
+      width: 1920,
+      height: 1080
+    }))
+    createR2AssetMock.mock.mockImplementation(async () => ({
+      id: 'asset-1',
+      uploadUrl: 'https://upload.example.com/video.mp4',
+      publicUrl: 'https://cdn.example.com/video.mp4'
+    }))
+    uploadToR2Mock.mock.mockImplementation(async () => {
+      throw new Error('Public URL verification failed: HEAD 403 Forbidden')
+    })
+    mock.method(console, 'error', () => {})
+    const summary = createProcessingSummary(1)
+
+    await processVideoFile(
+      '0_JesusVisionJohn---base---3934---1.mp4',
+      '/tmp/0_JesusVisionJohn---base---3934---1.mp4',
+      1024,
+      summary
+    )
+
+    assert.equal(summary.failed, 1)
+    assert.equal(formatR2AssetDiagnosticMock.mock.calls.length, 1)
+    assert.equal(requestMock.mock.calls.length, 0)
+    assert.equal(markFileAsCompletedMock.mock.calls.length, 0)
+    const failure = summary.failedFiles?.[0]
+    assert.ok(
+      failure?.reason?.startsWith('R2 upload/public verification:'),
+      'failure reason should be prefixed with R2 upload/public verification'
+    )
+    assert.ok(
+      failure?.reason?.includes('assetId=test-asset'),
+      'failure reason should include diagnostic info from formatR2AssetDiagnostic'
+    )
+  })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/video-importer/src/importers/video.spec.ts` around lines 108 - 146, The
success test needs to assert that the created R2 asset's publicUrl is forwarded
to uploadToR2 and you must add a new failure test that simulates uploadToR2
rejecting and verifies the recorded failure message includes
formatR2AssetDiagnostic(r2Asset) output; update the existing spec using the
existing helpers (createProcessingSummary and processVideoFile) by changing the
success case to inspect uploadToR2Mock.mock.calls[0] to ensure the
second/appropriate argument equals the publicUrl from createR2AssetMock, and add
a new it(...) that mocks createR2AssetMock to return a known
uploadUrl/publicUrl, makes uploadToR2Mock.mockImplementation(async () => { throw
new Error("upload failed") }), runs processVideoFile, and then asserts
summary.failed === 1 and that summary.failedFiles or failure messages contain
the formatted diagnostic string produced by formatR2AssetDiagnostic(r2Asset).

56-58: 💤 Low value

Avoid any in test helper; type the module-exports shape.

getModuleExports returns any, which propagates loosely-typed VIDEO_FILENAME_REGEX / processVideoFile assignments below. For ES module imports under node:test, the dynamic import() already yields the namespace object; the module.exports / default fallbacks here are unlikely to be needed, and the function can simply return the typed module.

As per coding guidelines: "Define a type if possible."

Proposed fix
-function getModuleExports<T>(module: T): any {
-  return (module as any)['module.exports'] ?? (module as any).default ?? module
-}
+function getModuleExports<T extends object>(module: T): T {
+  return module
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/video-importer/src/importers/video.spec.ts` around lines 56 - 58,
getModuleExports currently returns any and uses CommonJS fallbacks; change it to
return a properly typed module so VIDEO_FILENAME_REGEX and processVideoFile are
strongly typed. Replace the body with a simple identity that returns the generic
type: change the signature to getModuleExports<T>(module: T): T and return
module (remove the module.exports/default fallbacks), or define a specific
interface (e.g. { VIDEO_FILENAME_REGEX: RegExp; processVideoFile:
(...args:any[]) => any }) and use getModuleExports<ThatInterface>(...) so
callers (VIDEO_FILENAME_REGEX, processVideoFile) get correct types.
apps/video-importer/src/video-importer.ts (1)

215-237: ⚡ Quick win

Drop the post-run Slack config branches after preflight.

Once checkStartupEnvironment() has let the run continue, missing or partial Slack credentials should already have terminated the process. Keeping these checks here leaves a second source of truth that can drift from the preflight rules; this can simplify to a single !options.dryRun && options.slack gate.

Possible simplification
-  const slackTokenConfigured =
-    typeof process.env.SLACK_BOT_TOKEN === 'string' &&
-    process.env.SLACK_BOT_TOKEN.trim().length > 0
-  const slackChannelConfigured =
-    typeof process.env.SLACK_CHANNEL_ID === 'string' &&
-    process.env.SLACK_CHANNEL_ID.trim().length > 0
-
-  if (
-    !options.dryRun &&
-    options.slack &&
-    slackTokenConfigured !== slackChannelConfigured
-  ) {
-    console.warn(
-      '[video-importer] Slack is partially configured: set both SLACK_BOT_TOKEN and SLACK_CHANNEL_ID to enable notifications.'
-    )
-  }
-
-  if (
-    !options.dryRun &&
-    options.slack &&
-    slackTokenConfigured &&
-    slackChannelConfigured
-  ) {
+  if (!options.dryRun && options.slack) {
     try {
       const { postVideoImporterSlackSummary } = await import(
         /* webpackChunkName: "video-importer-slack" */ './services/slack'
       )
       await postVideoImporterSlackSummary({ folderPath, summary })

As per coding guidelines, keep failure paths explicit: log the failing stage, increment summary.failed, and return before later side effects.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/video-importer/src/video-importer.ts` around lines 215 - 237, The Slack
pre/post-run checks duplicate logic already enforced by
checkStartupEnvironment(); remove the partial-configuration branches around the
slackTokenConfigured/slackChannelConfigured booleans and replace the two
conditional blocks with a single guard if (!options.dryRun && options.slack)
that assumes preflight validated credentials; if you must handle a failure here
instead, make the failure path explicit by logging the failing stage (e.g.,
using processLogger or console.warn), incrementing summary.failed, and returning
immediately so later side-effects are not executed; reference the existing
symbols options, checkStartupEnvironment, summary.failed, slackTokenConfigured
and slackChannelConfigured to locate and simplify the logic.
apps/video-importer/src/startupPreflight.ts (1)

5-21: ⚡ Quick win

Use a single shared env schema to prevent drift.

requiredEnvSchema duplicates the contract in env.ts, which can silently diverge and cause inconsistent startup/runtime validation. Consider exporting a shared schema fragment and reusing it in both places.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/video-importer/src/startupPreflight.ts` around lines 5 - 21,
requiredEnvSchema duplicates the same contract in env.ts; export the common
schema from env.ts (e.g., export const baseEnvSchema or sharedRequiredEnvSchema)
and import it here instead of redefining everything, then use
z.object({...shared fields...}) or z.intersection/shared .extend to compose any
local additions so both startupPreflight.ts's requiredEnvSchema and the runtime
env validation share the exact same schema symbol (reference requiredEnvSchema
-> sharedRequiredEnvSchema and the env.ts export names in your edits).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@apps/video-importer/src/services/r2.ts`:
- Around line 182-196: The verification currently accepts a 200 response and
then calls rangeResponse.arrayBuffer(), which can download the entire object if
the CDN ignores the Range header; change the logic in the verification block to
either reject any non-206 status (i.e., throw unless rangeResponse.status ===
206) or, if you must accept 200, avoid arrayBuffer() and instead read only the
first byte via the streaming API (use rangeResponse.body.getReader().read() or
response.arrayBuffer slice techniques) and validate bytes.byteLength > 0 before
closing the reader; update the code around the Range request and the use of
rangeResponse.arrayBuffer() accordingly to prevent full-body buffering (refer to
the rangeResponse variable and the Range request with
R2_PUBLIC_URL_VERIFY_TIMEOUT_MS).
- Around line 168-173: The strict string equality check between
headResponse.headers.get('content-length') and String(expectedContentLength) is
fragile; change the check to parse the header when present (e.g., const cl =
headResponse.headers.get('content-length'); if (cl != null) { const parsed =
Number(cl); if (Number.isFinite(parsed) && parsed !== expectedContentLength)
throw new Error(...); } ) and skip/avoid throwing when the header is missing or
unparsable (optionally log a warning) — keep the numeric comparison against
expectedContentLength and retain the overall verifyFileUpload flow.

In `@apps/video-importer/src/services/slack.ts`:
- Around line 444-470: The Slack alert text currently blames the shipped .env
file; update the message produced in the postSlackMessage call (the block that
uses hostname, errorLines and extraLine) so it describes an invalid runtime
configuration instead (e.g., "The importer could not start on `hostname` due to
invalid runtime configuration/overrides") and change the remediation text in the
context element (currently referencing the shipped .env) to a runtime-agnostic,
actionable instruction (e.g., verify environment variables, secrets and shell
overrides or reconfigure the runtime) while keeping checkStartupEnvironment() as
the validation source and preserving existing variables (hostname, errorLines,
extraLine).

In `@apps/video-importer/test-videos/.gitignore`:
- Around line 2-7: Add ignore patterns for `.failed` fixture artifacts: update
the .gitignore used for test fixtures to include a generic *.failed plus the
specific extension variants (*.mp4.failed, *.srt.failed, *.aac.failed) so the
importer-created .failed status files cannot be accidentally committed; ensure
these patterns appear alongside the existing *.mp4, *.mp4.completed, *.srt,
*.srt.completed, *.aac, and *.aac.completed entries.

In `@apps/video-importer/test-videos/README.md`:
- Line 14: Update the README sentence that currently states "It also recreates
the intentionally invalid MP4 and subtitle fixture" to accurately reflect that
only the MP4 fixture is intentionally invalid; change the phrase to something
like "It also recreates the intentionally invalid MP4 fixture and the valid
subtitle fixture" so readers are not misled — search for the phrase
"intentionally invalid MP4 and subtitle fixture" in README.md to locate and edit
the line.

---

Nitpick comments:
In `@apps/video-importer/src/importers/video.spec.ts`:
- Around line 108-146: The success test needs to assert that the created R2
asset's publicUrl is forwarded to uploadToR2 and you must add a new failure test
that simulates uploadToR2 rejecting and verifies the recorded failure message
includes formatR2AssetDiagnostic(r2Asset) output; update the existing spec using
the existing helpers (createProcessingSummary and processVideoFile) by changing
the success case to inspect uploadToR2Mock.mock.calls[0] to ensure the
second/appropriate argument equals the publicUrl from createR2AssetMock, and add
a new it(...) that mocks createR2AssetMock to return a known
uploadUrl/publicUrl, makes uploadToR2Mock.mockImplementation(async () => { throw
new Error("upload failed") }), runs processVideoFile, and then asserts
summary.failed === 1 and that summary.failedFiles or failure messages contain
the formatted diagnostic string produced by formatR2AssetDiagnostic(r2Asset).
- Around line 56-58: getModuleExports currently returns any and uses CommonJS
fallbacks; change it to return a properly typed module so VIDEO_FILENAME_REGEX
and processVideoFile are strongly typed. Replace the body with a simple identity
that returns the generic type: change the signature to
getModuleExports<T>(module: T): T and return module (remove the
module.exports/default fallbacks), or define a specific interface (e.g. {
VIDEO_FILENAME_REGEX: RegExp; processVideoFile: (...args:any[]) => any }) and
use getModuleExports<ThatInterface>(...) so callers (VIDEO_FILENAME_REGEX,
processVideoFile) get correct types.

In `@apps/video-importer/src/startupPreflight.ts`:
- Around line 5-21: requiredEnvSchema duplicates the same contract in env.ts;
export the common schema from env.ts (e.g., export const baseEnvSchema or
sharedRequiredEnvSchema) and import it here instead of redefining everything,
then use z.object({...shared fields...}) or z.intersection/shared .extend to
compose any local additions so both startupPreflight.ts's requiredEnvSchema and
the runtime env validation share the exact same schema symbol (reference
requiredEnvSchema -> sharedRequiredEnvSchema and the env.ts export names in your
edits).

In `@apps/video-importer/src/video-importer.ts`:
- Around line 215-237: The Slack pre/post-run checks duplicate logic already
enforced by checkStartupEnvironment(); remove the partial-configuration branches
around the slackTokenConfigured/slackChannelConfigured booleans and replace the
two conditional blocks with a single guard if (!options.dryRun && options.slack)
that assumes preflight validated credentials; if you must handle a failure here
instead, make the failure path explicit by logging the failing stage (e.g.,
using processLogger or console.warn), incrementing summary.failed, and returning
immediately so later side-effects are not executed; reference the existing
symbols options, checkStartupEnvironment, summary.failed, slackTokenConfigured
and slackChannelConfigured to locate and simplify the logic.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 4459711d-0ebe-433b-a16a-56ac05e98ecb

📥 Commits

Reviewing files that changed from the base of the PR and between 1fea2b3 and cc5c967.

📒 Files selected for processing (17)
  • apps/video-importer/AGENTS.md
  • apps/video-importer/README.md
  • apps/video-importer/src/env.ts
  • apps/video-importer/src/gql/graphqlClient.ts
  • apps/video-importer/src/importers/audiopreview.ts
  • apps/video-importer/src/importers/subtitle.ts
  • apps/video-importer/src/importers/video.spec.ts
  • apps/video-importer/src/importers/video.ts
  • apps/video-importer/src/services/r2.ts
  • apps/video-importer/src/services/slack.ts
  • apps/video-importer/src/startupPreflight.ts
  • apps/video-importer/src/types.ts
  • apps/video-importer/src/utils/startupPreflight.spec.ts
  • apps/video-importer/src/video-importer.ts
  • apps/video-importer/test-videos/.gitignore
  • apps/video-importer/test-videos/README.md
  • apps/video-importer/test-videos/reset-fixtures.sh

Comment thread apps/video-importer/src/services/r2.ts Outdated
Comment thread apps/video-importer/src/services/r2.ts Outdated
Comment thread apps/video-importer/src/services/slack.ts
Comment thread apps/video-importer/test-videos/.gitignore
Comment thread apps/video-importer/test-videos/README.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants