Skip to content

Automated Repository Validation Workflow

Quantumrunner edited this page Apr 24, 2026 · 2 revisions

Automated Repository Validation Workflow

This document explains how the automated GitHub Actions validation works for Scenarios and Custom Content Packs submitted to the valkyrie-store.

Overview

When a creator submits a new scenario or content pack via a GitHub Issue using the provided issue templates, a GitHub Actions workflow automatically clones their repository and validates its structure. This ensures only functional, conflict-free content makes it into the Valkyrie app without manual testing by a maintainer on every submission.

Triggers

The validation workflow (.github/workflows/validate-repo.yml) triggers under three conditions:

  1. New Issue Opened: When an issue is opened with a title starting with [Scenario] or [ContentPack].
  2. Issue Comment: When a maintainer or author comments /check or /revalidate on an existing submission issue.
  3. Manual Dispatch: Maintainers can manually trigger it via the "Actions" tab by providing a raw repository URL.

What Gets Validated?

The script (workflowScripts/validate-repo.ps1) dynamically detects if the repository is a Scenario or a Content Pack and applies different conditions accordingly.

1. Repository-Level Checks

  • Repository Name: Warns if the repository name contains a hyphen (-), recommending dots (.) instead for convention.
  • Image File: Confirms the presence of at least one .jpg or .png file in the tree.
  • Unique IDs: Extracts the content ID from the container filename (e.g. .valkyrie or .valkyrieContentPack) and cross-references it against the live valkyrie-store manifests to absolutely prevent duplicate IDs across the ecosystem.

2. Base Configuration Checks (.ini)

  • Language: Reads the defaultlanguage (or Language) from the .ini file. Warns if left as English just in case the creator forgot to change it for regional scenarios.
  • Type Property: Ensures the type property is set correctly depending on the content structure (e.g. MoM, D2E for Scenarios; MoMCustom, D2ECustom for Content Packs).
  • Missing Thumbnails: Verifies that the image explicitly declared in the .ini actually exists in the repository.

3. Scenario-Specific Checks

  • Required Files: Expects at least one .ini and one .valkyrie file.
  • Generic Names: Rejects files named EditorScenario1 or similar placeholder names to force descriptive naming.
  • Expansions: Extracts and outputs the packs= property so maintainers can visually verify it matches the user's issue form.

4. Content Pack-Specific Checks

  • Required Files: Expects at least one .valkyrieContentPack and one .ini file.
  • UI Element Properties: Strictly verifies that name.{Language} and description.{Language} are defined, as the app's ContentSelectDownloadScreen requires these to display the UI correctly.

5. Container File Integrity Checks (.valkyrie / .valkyrieContentPack)

The validator performs two layers of checks on every container file to catch corrupt or unservable files before they reach users.

Size checks (via the GitHub tree API):

  • Under 1 024 bytes: Almost certainly an unresolved Git LFS pointer served in place of the real file, or an empty file. Users will be unable to open the scenario. The file must be committed as a regular Git object (not via LFS).
  • Over 100 MB: Exceeds GitHub's raw-serving limit. Users will be unable to download it. Large assets must be removed or compressed.

ZIP magic-byte check (via HTTP Range request on the first 8 bytes):

  • ✅ Header 50 4B 03 04 — valid ZIP archive. Reports the file size in MB.
  • ❌ Header starts with version — this is a Git LFS pointer being served instead of the real file, even though the file size appeared normal. The .valkyrie extension must be excluded from LFS tracking.
  • ❌ Any other header — the file is corrupt or was not packaged correctly. The unexpected bytes are reported to help diagnose the issue.

Why this matters: The most common failure mode seen in the wild is a scenario committed via Git LFS. GitHub serves LFS-tracked files as small text pointer files (~130 bytes) to anonymous users, so the Valkyrie app receives a text file instead of a ZIP and crashes when trying to open it. These checks catch that problem at submission time rather than after the scenario is already listed in the store.

Maintainer Helpers

When a repository successfully passes all critical validation checks (i.e. valid Type, valid components, unique ID), the action goes a step further and automatically generates a Manifest Editor Snippet.

This provides the exact block of INI text needed to add the repository to the Valkyrie Store, along with a direct 1-click URL to edit the manifest.ini or contentPacksManifest.ini file right on GitHub!

Example:

[CityOfTheDead]
external=https://raw.githubusercontent.com/Quantumrunner/ValkyrieCityOfTheDead/master/

How to Handle Fixes

If validation fails:

  1. Copy the error (or simply reply) to advise the author on what the script tripped over.
  2. The author fixes their repository and pushes the changes to GitHub.
  3. Once the fixes are pushed, simply comment /check or /revalidate on the issue thread to instantly command the Validation Bot to re-run and confirm.

Clone this wiki locally