Skip to content

GitHub Actions Auto Build

Manually compiling, packaging, and uploading Releases is tedious. With GitHub Actions, CI/CD can automate it all: push code → auto-compile → auto-package → auto-publish.

Why You Need a Private Lib Repository

ADOFAI Mods must reference the game's original DLLs (Assembly-CSharp.dll, etc.) at compile time. But these DLLs are copyright-protected and cannot be placed in public repositories.

The solution: create a private repository specifically to store these binaries, and use a token to access it during CI builds. This is the "private lib repository" approach.

Never put original binaries in public repositories or Releases — see Development Guidelines.

Step 1: Prepare the Private Lib Repository

  1. Create a private repository, e.g. my-mods-libs

  2. Place the original DLLs from the game directory A Dance of Fire and Ice\ADofAI_Data\Managed\ into it (keep the same directory structure):

    my-mods-libs/
    └── Managed/
        ├── Assembly-CSharp.dll
        ├── UnityEngine.dll
        ├── UnityEngine.CoreModule.dll
        └── ...
  3. Push to GitHub (the repository is private, so binaries won't be exposed)

These DLLs are build dependencies only — don't modify, don't distribute, for CI internal use only.

Step 2: Create a Personal Access Token (PAT)

CI needs permission to clone the private repository:

  1. GitHub → Settings → Developer settings → Personal access tokens → Fine-grained tokens
  2. Create a new token with only:
    • Repository access: select your private lib repository
    • Contents → Read (read permission)
  3. Copy the token value

Step 3: Store the PAT as a Secret

In your Mod repository:

  1. Settings → Secrets and variables → Actions
  2. New repository secret
  3. Name: LIBS_PAT (or any name), value: paste the token from the previous step

Secrets don't appear in logs. In CI, use ${{ secrets.LIBS_PAT }}.

Step 4: Write the Actions Workflow

Create .github/workflows/build.yml in your repository:

yaml
name: Build

on:
  push:
    tags:
      - "v*"        # Trigger on tag push

jobs:
  build:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      # 1. Clone the private lib repository (using PAT)
      - name: Clone private libs
        run: |
          git clone https://${{ secrets.LIBS_PAT }}@github.com/yourname/my-mods-libs.git libs

      # 2. Install .NET
      - uses: actions/setup-dotnet@v4
        with:
          dotnet-version: "8.x"

      # 3. Build (referencing DLLs under libs/)
      - name: Build
        run: dotnet build MyFirstMod.csproj -c Release -p:ADOFAI_PATH=libs

      # 4. Package the Mod directory
      - name: Package
        shell: pwsh
        run: |
          $mod = "MyFirstMod"
          New-Item -ItemType Directory -Path dist/$mod -Force | Out-Null
          Copy-Item MyFirstMod/bin/Release/**/*.dll dist/$mod/
          Copy-Item Info.json dist/$mod/
          Copy-Item README.md dist/$mod/

      # 5. Publish to Release
      - uses: softprops/action-gh-release@v2
        with:
          files: dist/MyFirstMod/*

Making csproj Support the libs Path

The workflow passes the lib repository path via -p:ADOFAI_PATH=libs. Your .csproj should use this property:

xml
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net48</TargetFramework>
    <!-- Local path: your game directory -->
    <ADOFAI_PATH Condition="'$(ADOFAI_PATH)' == ''">D:\Steam\steamapps\common\A Dance of Fire and Ice</ADOFAI_PATH>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="Assembly-CSharp">
      <HintPath>$(ADOFAI_PATH)\ADofAI_Data\Managed\Assembly-CSharp.dll</HintPath>
      <Private>false</Private>
    </Reference>
  </ItemGroup>
</Project>
  • Condition: when CI passes ADOFAI_PATH, it uses the CI path; for local development, it uses the default game path
  • <Private>false</Private>: don't copy game DLLs into the output directory

Workflow Breakdown

StepPurpose
checkout@v4Pull your Mod source code
Clone private libsPull binary dependencies using secrets.LIBS_PAT
setup-dotnetPrepare the build environment
dotnet buildCompile Release
PackageAssemble the Mods/MyFirstMod/ directory structure
action-gh-releaseUpload to Release assets

Trigger

yaml
on:
  push:
    tags:
      - "v*"

Push a tag like v1.0.0 to auto-build and publish:

bash
git tag v1.0.0
git push origin v1.0.0

Common Issues

Build can't find game DLLs?

Confirm the private lib repository directory structure matches the HintPath in .csproj (both should use ADofAI_Data/Managed/).

Secret name wrong?

In the Actions run log, using the wrong name for ${{ secrets.XXX }} will silently substitute an empty string. Check that the Secret name matches exactly.

PAT lacks clone permission?

Confirm the PAT has Contents: Read permission and that repository access only checks the lib repository.

What You Learned

  • Why you need a private lib repository
  • How to create a PAT and configure a Secret
  • The complete CI workflow and csproj adaptation

Next Step

Read the guidelines before publishing → Development Guidelines

An organization that researches and expands the functions of ADOFAI