Skip to content

Epic Games Store Deployment

Summary: Builds are uploaded to the Epic Games Store using the standalone BuildPatchTool (BPT). The Live label activates a build within its sandbox scope. Dev and release builds both upload automatically, while a standalone workflow allows manual uploads of existing builds.

Table of Contents


Architecture Overview

┌─────────────────────┐       ┌──────────────────────┐       ┌──────────────┐
│  Packaged Build     │       │  BuildPatchTool       │       │  Epic Games  │
│  C:\BuildArtifacts\ │──────▶│  UploadBinary         │──────▶│  Store       │
│  <run_number>\      │       │  LabelBinary          │       │  Dev Portal  │
└─────────────────────┘       └──────────────────────┘       └──────────────┘
                                       │ credentials
                              ┌──────────────────────┐
                              │  GitHub Secrets       │
                              │  EGS_ORGANIZATION_ID  │
                              │  EGS_PRODUCT_ID       │
                              │  EGS_ARTIFACT_ID      │
                              │  EGS_CLIENT_ID        │
                              │  EGS_CLIENT_SECRET    │
                              │  EGS_SANDBOX_ID       │
                              └──────────────────────┘

BuildPatchTool (BPT)

Standalone vs Engine-Bundled

Version Location Capabilities
Standalone (required) C:\Tools\BuildPatchTool\ UploadBinary, LabelBinary, CopyBinary
Engine-bundled UE_5.6\Engine\Binaries\Win64\ Offline modes only (PatchGeneration, etc.)

The engine-bundled BPT cannot upload to EGS. The standalone version must be downloaded from the Epic Dev Portal under Product Settings.

Authentication

BPT uses dedicated credentials separate from any EOS client IDs the game uses:

Parameter Value Notes
-ClientId Direct value The BPT client ID
-ClientSecretEnvVar Environment variable name Pass the env var name as a string, NOT the secret value
-OrganizationId Direct value Epic org ID
-ProductId Direct value Product ID from Dev Portal
-ArtifactId Direct value Artifact ID from Dev Portal
-SandboxId Direct value Required for self-publishing orgs

Important: -ClientSecretEnvVar takes the name of the environment variable (e.g., "EGS_CLIENT_SECRET"), not the actual secret value.


Labels

BPT only supports two label names:

Label Effect
Live Marks the binary as the active/downloadable build within its sandbox
Archive Preserves the binary from auto-deletion but does not make it active

What Happens Without a Label

Unlabeled binaries are automatically deleted after approximately 7 days by EGS cleanup jobs.

Common Misconception

Live does not mean "released to the public." It means "active build" within the sandbox scope. A Live label in the Dev sandbox only affects dev testing — it does not publish to end users.

Custom label names (e.g., Dev, Staging, QA) are not valid and will produce the error:

Labeling operations are not permitted on the provided label: [Dev]


Sandboxes

EGS uses sandboxes to isolate environments:

Sandbox Purpose
Dev Internal testing and development
Stage Pre-release validation
Live Public distribution to players

The -SandboxId parameter is required for self-publishing organizations. Without it, LabelBinary fails with:

There was a permissions issue with the labelling operation.

Each sandbox has its own set of active binaries and deployment IDs. Labeling a build as Live in the Dev sandbox does not affect the Live sandbox.


Upload Flow

Automated (via build-and-package.yml)

Build Completes
Upload Step Runs? ──No──▶ (main branch: skip)
     Yes (dev, release/*)
UploadBinary ──▶ Chunks build, uploads to EGS
LabelBinary ──▶ Applies "Live" label (makes it active)
Discord Notification

Version Format

Trigger Version Format Example
Automated build YYYY.MM.DD-<run>-<sha> 2026.02.27-18-1a087dc9
Manual standalone upload manual-<build_number>-<run> manual-18-7

Standalone Upload Workflow

For uploading existing builds without rebuilding:

Input Description Default
build_number Folder name in C:\BuildArtifacts\ Required
label Live, Archive, or None Live

Trigger manually from GitHub Actions > "Upload to EGS (standalone)" > Run workflow.

The workflow searches for ProjectEternal.exe in the build directory under Windows/, WindowsNoEditor/, or the root.


Troubleshooting

Common Errors

Error Cause Fix
UploadBinary is not a supported mode Using engine-bundled BPT Install standalone BPT from Dev Portal
Labeling operations are not permitted on the provided label Invalid label name (e.g., Dev) Use only Live or Archive
permissions issue with the labelling operation Missing SandboxId Set EGS_SANDBOX_ID secret
Failed to retrieve list of binaries Wrong credentials Verify EGS_CLIENT_ID and EGS_CLIENT_SECRET
Label step fails but upload succeeded Non-fatal Build is uploaded; apply label manually from Dev Portal

PowerShell Gotchas in GitHub Actions

Issue Solution
Single quotes in double-quoted strings break parsing Use string concatenation: ("text " + $var + " text")
Write-Warning propagates non-zero exit codes Use Write-Output for non-fatal warnings
Non-zero $LASTEXITCODE from previous command Reset with $global:LASTEXITCODE = 0


Source References

File Purpose
.github/workflows/build-and-package.yml Automated upload after build (upload-egs job)
.github/workflows/upload-egs.yml Standalone manual upload workflow

Recent Changes

Date Change Impact
2026-03-02 Created documentation Initial EGS deployment docs
2026-02-27 Labels fixed to Live/Archive only Dev label was invalid, caused failures
2026-02-27 SandboxId support added Required for self-publishing org label operations
2026-02-27 Standalone BPT installed Engine-bundled BPT lacks upload capability
2026-02-27 All branches label as Live Live = active in sandbox scope, not public release