Skip to content
Open
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
47 changes: 47 additions & 0 deletions .github/scripts/inject-token.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
param(
[string]$Token
)

if ([string]::IsNullOrEmpty($Token)) {
# For PRs from forks, secrets are not available. We use a dummy token to allow the build to pass.
if ($env:GITHUB_EVENT_NAME -eq 'pull_request') {
Write-Host "Warning: No UPLOADTHING_TOKEN provided. Using dummy token for PR build."
$Token = "DUMMY_TOKEN_FOR_CI_ONLY"
} else {
Write-Error "No UPLOADTHING_TOKEN provided. Fails for Release builds."
exit 1
}
}

$constantsPath = "GenHub/GenHub.Core/Constants/ApiConstants.cs"
if (-not (Test-Path $constantsPath)) {
Write-Error "Could not find $constantsPath"
exit 1
}

$tokenBytes = [System.Text.Encoding]::UTF8.GetBytes($Token)
$key = New-Object byte[] 32
[System.Security.Cryptography.RandomNumberGenerator]::Create().GetBytes($key)

$obfuscated = New-Object byte[] $tokenBytes.Length
for ($i = 0; $i -lt $tokenBytes.Length; $i++) {
$obfuscated[$i] = $tokenBytes[$i] -bxor $key[$i % $key.Length]
}

$dataStr = ($obfuscated | ForEach-Object { "0x{0:x2}" -f $_ }) -join ", "
$keyStr = ($key | ForEach-Object { "0x{0:x2}" -f $_ }) -join ", "

$content = Get-Content $constantsPath -Raw

# Use regex replace to be robust against whitespace
# Pattern: byte[] data = []; // [PLACEHOLDER_DATA]
$content = [System.Text.RegularExpressions.Regex]::Replace($content, 'byte\[\]\s+data\s*=\s*\[\];\s*//\s*\[PLACEHOLDER_DATA\]', "byte[] data = [$dataStr];")
$content = [System.Text.RegularExpressions.Regex]::Replace($content, 'byte\[\]\s+key\s*=\s*\[\];\s*//\s*\[PLACEHOLDER_KEY\]', "byte[] key = [$keyStr];")

if ($content -notmatch "0x") {
Write-Error "Token injection failed! Placeholders were not found or replaced."
exit 1
}

Set-Content $constantsPath $content
Write-Host "Successfully injected and obfuscated UPLOADTHING_TOKEN into ApiConstants.cs"
11 changes: 11 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,11 @@ jobs:
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
echo "CHANNEL=$channel" >> $env:GITHUB_OUTPUT

- name: Inject Secrets
shell: pwsh
run: |
./.github/scripts/inject-token.ps1 -Token "${{ secrets.UPLOADTHING_TOKEN }}"

- name: Build Projects
shell: pwsh
run: |
Expand All @@ -142,6 +147,7 @@ jobs:
Write-Host "Building Windows project"
dotnet build "${{ env.WINDOWS_PROJECT }}" -c ${{ env.BUILD_CONFIGURATION }} @buildProps


- name: Publish Windows App
shell: pwsh
run: |
Expand Down Expand Up @@ -279,6 +285,11 @@ jobs:
echo "PR_NUMBER=$PR_NUMBER" >> $GITHUB_OUTPUT
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT

- name: Inject Secrets
shell: pwsh
run: |
./.github/scripts/inject-token.ps1 -Token "${{ secrets.UPLOADTHING_TOKEN }}"

- name: Build Projects
run: |
BUILD_PROPS="-p:Version=${{ steps.buildinfo.outputs.VERSION }} -p:GitShortHash=${{ steps.buildinfo.outputs.SHORT_HASH }} -p:PullRequestNumber=${{ steps.buildinfo.outputs.PR_NUMBER }} -p:BuildChannel=${{ steps.buildinfo.outputs.CHANNEL }}"
Expand Down
53 changes: 53 additions & 0 deletions .github/workflows/github-pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
name: Deploy Landing Page to GitHub Pages

on:
workflow_run:
workflows: ["GenHub Release"]
types: [completed]
workflow_dispatch:

permissions:
contents: write
pages: write
id-token: write

jobs:
deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}

steps:
- uses: actions/checkout@v4

- uses: actions/configure-pages@v5

- id: release_info
env:
GH_TOKEN: ${{ github.token }}
run: |
LATEST_TAG=$(gh release list --limit 1 --json tagName -q '.[0].tagName')

BUILD_NUM=$(echo "$LATEST_TAG" | cut -d'.' -f3)
DISPLAY_NAME="Alpha ${BUILD_NUM}"

echo "latest_tag=$LATEST_TAG" >> $GITHUB_OUTPUT
echo "display_name=$DISPLAY_NAME" >> $GITHUB_OUTPUT

- run: |
mkdir -p ./public
cp Landing-page/index.html ./public/index.html

if [ -d "Landing-page/assets" ]; then
cp -r Landing-page/assets ./public/assets
fi

DOWNLOAD_URL="https://github.com/community-outpost/GenHub/releases/download/${{ steps.release_info.outputs.latest_tag }}/GenHub-win-Setup.exe"

sed -i "s|VERSION_PLACEHOLDER|${{ steps.release_info.outputs.display_name }}|g" ./public/index.html
sed -i "s|URL_PLACEHOLDER|${DOWNLOAD_URL}|g" ./public/index.html

- uses: actions/upload-pages-artifact@v3
with:
path: ./public

- uses: actions/deploy-pages@v4
22 changes: 16 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ jobs:
$version = "0.0.${{ github.run_number }}"
echo "VERSION=$version" >> $env:GITHUB_OUTPUT

- name: Inject Secrets
shell: pwsh
run: |
./.github/scripts/inject-token.ps1 -Token "${{ secrets.UPLOADTHING_TOKEN }}"

- name: Publish Windows App
shell: pwsh
run: |
Expand Down Expand Up @@ -68,7 +73,7 @@ jobs:
--packAuthors "Community Outpost" `
--icon GenHub/GenHub/Assets/Icons/generalshub.ico `
--outputDir velopack-release-windows

# Rename metadata to prevent collisions with Linux
Rename-Item -Path "velopack-release-windows\releases.json" -NewName "releases.win.json" -ErrorAction SilentlyContinue
Rename-Item -Path "velopack-release-windows\assets.json" -NewName "assets.win.json" -ErrorAction SilentlyContinue
Expand Down Expand Up @@ -111,6 +116,11 @@ jobs:
- name: Install Linux Dependencies
run: sudo apt-get update && sudo apt-get install -y libgtk-3-dev libx11-dev

- name: Inject Secrets
shell: pwsh
run: |
./.github/scripts/inject-token.ps1 -Token "${{ secrets.UPLOADTHING_TOKEN }}"

- name: Publish Linux App
run: |
dotnet publish "${{ env.LINUX_PROJECT }}" \
Expand All @@ -136,7 +146,7 @@ jobs:
--packAuthors "Community Outpost" \
--icon GenHub/GenHub/Assets/Icons/generalshub-icon.png \
--outputDir velopack-release-linux

# Rename metadata to prevent collisions with Windows
mv velopack-release-linux/releases.json velopack-release-linux/releases.linux.json || true
mv velopack-release-linux/assets.json velopack-release-linux/assets.linux.json || true
Expand Down Expand Up @@ -194,7 +204,7 @@ jobs:
find artifacts/linux-release -type f \( -name "*.nupkg" -o -name "*.json" \) -exec cp {} final-assets/ \;
# 3. Windows Portable (Specific match)
cp artifacts/windows-portable/*.zip final-assets/

ls -lh final-assets/

- name: Create Release
Expand All @@ -205,12 +215,12 @@ jobs:
prerelease: true
body: |
## GenHub Alpha v${{ steps.info.outputs.VERSION }}

### 🆕 What's New
**${{ steps.info.outputs.COUNT }} commits** included:
${{ steps.info.outputs.CHANGELOG }}

### 🔧 Assets
- **Installer:** `GenHub-win-Setup.exe`
- **Portable:** `GenHub-${{ steps.info.outputs.VERSION }}-win-portable.zip`
- **Installer:** [GenHub-win-Setup.exe](https://github.com/${{ github.repository }}/releases/download/v${{ steps.info.outputs.VERSION }}/GenHub-win-Setup.exe)
- **Portable:** [GenHub-${{ steps.info.outputs.VERSION }}-win-portable.zip](https://github.com/${{ github.repository }}/releases/download/v${{ steps.info.outputs.VERSION }}/GenHub-${{ steps.info.outputs.VERSION }}-win-portable.zip)
files: final-assets/*
20 changes: 14 additions & 6 deletions GenHub/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@
Alpha versioning: 0.0.X format
CI will override with: 0.0.{runNumber} or 0.0.{runNumber}-pr{prNumber}
-->
<Version>0.0.1</Version>
<AssemblyVersion>0.0.1.0</AssemblyVersion>
<FileVersion>0.0.1.0</FileVersion>
<Version Condition="'$(Version)' == ''">0.0.1</Version>

<!--
AssemblyVersion and FileVersion must be strictly numeric (x.y.z.w)
Strip any prerelease suffix (e.g., -pr238) from Version for these properties
-->
<_NumericVersion Condition="$(Version.Contains('-'))">$(Version.Substring(0, $(Version.IndexOf('-'))))</_NumericVersion>
<_NumericVersion Condition="!$(Version.Contains('-'))">$(Version)</_NumericVersion>
<AssemblyVersion>$(_NumericVersion)</AssemblyVersion>
<FileVersion>$(_NumericVersion)</FileVersion>

<!-- Make version available to source generators / build-time code -->
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
Expand All @@ -15,15 +22,16 @@
Build info for CI - these are overridden by CI workflow via MSBuild properties:
dotnet build -p:GitShortHash=abc1234 -p:PullRequestNumber=42 -p:BuildChannel=PR
-->
<GitShortHash></GitShortHash>
<PullRequestNumber></PullRequestNumber>
<BuildChannel>Dev</BuildChannel>
<GitShortHash Condition="'$(GitShortHash)' == ''"></GitShortHash>
<PullRequestNumber Condition="'$(PullRequestNumber)' == ''"></PullRequestNumber>
<BuildChannel Condition="'$(BuildChannel)' == ''">Dev</BuildChannel>

<!--
Include git hash in InformationalVersion for display
Results in: "0.0.150+abc1234" for CI builds
-->
<InformationalVersion Condition="'$(GitShortHash)' != ''">$(Version)+$(GitShortHash)</InformationalVersion>
<InformationalVersion Condition="'$(GitShortHash)' == ''">$(Version)</InformationalVersion>
</PropertyGroup>

<!-- Embed build metadata in assembly for runtime access -->
Expand Down
2 changes: 2 additions & 0 deletions GenHub/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<PackageVersion Include="Avalonia.Desktop" Version="11.2.7" />
<PackageVersion Include="Avalonia.Themes.Fluent" Version="11.2.7" />
<PackageVersion Include="Avalonia.Fonts.Inter" Version="11.2.7" />
<PackageVersion Include="Avalonia.Controls.DataGrid" Version="11.2.7" />
<PackageVersion Include="Avalonia.Diagnostics" Version="11.2.7" />

<PackageVersion Include="CommunityToolkit.Mvvm" Version="8.2.1" />
Expand All @@ -27,6 +28,7 @@
<PackageVersion Include="ReactiveUI" Version="19.6.1" />
<PackageVersion Include="Serilog.Extensions.Logging.File" Version="3.0.0" />
<PackageVersion Include="Slugify.Core" Version="5.1.1" />
<PackageVersion Include="DotNetEnv" Version="3.1.1" />
<PackageVersion Include="StyleCop.Analyzers" Version="1.2.0-beta.556" />
<PackageVersion Include="CsvHelper" Version="33.1.0" />
<!-- Test packages -->
Expand Down
94 changes: 93 additions & 1 deletion GenHub/GenHub.Core/Constants/ApiConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,98 @@ public static class ApiConstants
/// </summary>
public const string GitHubApiRunArtifactsFormat = "https://api.github.com/repos/{0}/{1}/actions/runs/{2}/artifacts";

// UploadThing

/// <summary>
/// UploadThing API version.
/// </summary>
public const string UploadThingApiVersion = "7.7.4";

/// <summary>
/// UploadThing prepare upload URL.
/// </summary>
public const string UploadThingPrepareUrl = "https://api.uploadthing.com/v7/prepareUpload";

/// <summary>
/// UploadThing delete file URL.
/// </summary>
public const string UploadThingDeleteUrl = "https://api.uploadthing.com/v6/deleteFiles";

/// <summary>
/// UploadThing public file URL format.
/// </summary>
public const string UploadThingPublicUrlFormat = "https://utfs.io/f/{0}";

/// <summary>
/// UploadThing URL fragment for identification.
/// </summary>
public const string UploadThingUrlFragment = "utfs.io/f/";

/// <summary>
/// UploadThing token environment variable.
/// </summary>
public const string UploadThingTokenEnvVar = "UPLOADTHING_TOKEN";

/// <summary>
/// Alternative UploadThing token environment variable.
/// </summary>
public const string UploadThingTokenEnvVarAlt = "GENHUB_UPLOADTHING_TOKEN";

/// <summary>
/// Gets the default UploadThing token injected at build time (Obfuscated).
/// </summary>
public static string BuildTimeUploadThingToken
{
get
{
// This is a simple XOR obfuscation to prevent the raw token from appearing in strings/debuggers.
// The actual values are injected during the GitHub Actions build process.
byte[] data = []; // [PLACEHOLDER_DATA]
byte[] key = []; // [PLACEHOLDER_KEY]

if (data.Length == 0 || key.Length == 0) return string.Empty;

var result = new byte[data.Length];
for (int i = 0; i < data.Length; i++)
{
result[i] = (byte)(data[i] ^ key[i % key.Length]);
}

return System.Text.Encoding.UTF8.GetString(result);
}
}

/// <summary>
/// UploadThing API key header.
/// </summary>
public const string UploadThingApiKeyHeader = "x-uploadthing-api-key";

/// <summary>
/// UploadThing version header.
/// </summary>
public const string UploadThingVersionHeader = "x-uploadthing-version";

// Media Types

/// <summary>
/// Media type for ZIP files.
/// </summary>
public const string MediaTypeZip = "application/zip";

// GenTool

/// <summary>
/// GenTool data URL fragment for identification.
/// </summary>
public const string GenToolUrlFragment = "gentool.net/data/";

// Generals Online

/// <summary>
/// Generals Online view match URL fragment.
/// </summary>
public const string GeneralsOnlineViewMatchFragment = "playgenerals.online/viewmatch";

/// <summary>
/// Format string for GitHub API Workflow Runs endpoint (owner, repo).
/// </summary>
Expand All @@ -70,4 +162,4 @@ public static class ApiConstants
/// Gets the default user agent string for HTTP requests.
/// </summary>
public static string DefaultUserAgent => $"{AppConstants.AppName}/{AppConstants.AppVersion}";
}
}
Loading