name: Mod Build on: push: branches: - "**" workflow_dispatch: env: MOD_NAME: "RefinedRDApi" MOD_ID: "7q2RnptXynYzEX" SML_DIR: "S:/SML" ENGINE_DIR: "S:/UE" BUILT_MODS_DIR: "${{ gitea.workspace }}/BuiltMods" DEV_BUILDS_DIR: "${{ gitea.workspace }}/DevBuilds" MODS_TO_BUILD: "RefinedRDApi" MOD_DEPENDENCIES: "" IS_GAME_FEATURE_PLUGIN: "false" jobs: Details: runs-on: ubuntu-docker steps: - run: | echo "DEPLOY: ${{vars.DEPLOY}}" echo "DEVBUILD: ${{vars.DEVBUILD}}" echo "Branch/Tag: ${{gitea.ref_name}}" echo "Mod Name: ${{env.MOD_NAME}}" echo "SML Directory: ${{env.SML_DIR}}" echo "Engine Directory: ${{env.ENGINE_DIR}}" echo "Built Mods Directory: ${{env.BUILT_MODS_DIR}}" echo "Dev Build Directory: ${{env.DEV_BUILDS_DIR}}" echo "Change Log: auto-generated from commits since last release/* tag" Build: runs-on: windows-ue defaults: run: shell: pwsh outputs: version: ${{steps.version.outputs.version}} changelog_b64: ${{steps.changelog.outputs.changelog_b64}} steps: - name: Compute Version id: version run: | $year = (Get-Date).Year $month = (Get-Date).Month $quarter = [math]::Ceiling($month / 3) $quarterKey = "$year.$quarter" $response = curl -s -X POST ` -H "x-rp-key: ${{secrets.RRD_API_KEY}}" ` -H "Content-Type: application/json" ` -d "{`"quarter`":`"$quarterKey`"}" ` "${{secrets.RRD_API_URL}}/api/v1/mods/buildnumber/${{env.MOD_NAME}}/increment" | ConvertFrom-Json if (-not $response.build) { Write-Error "Failed to get build number from API" exit 1 } $version = "$quarterKey.$($response.build)" Write-Output "version=$version" >> $Env:GITHUB_OUTPUT echo "Computed version: $version" - name: Setup SML run: | if (Test-Path "${{env.SML_DIR}}/.git" -PathType Container) { cd ${{env.SML_DIR}} git fetch origin dev git reset --hard origin/dev } else { git clone --branch dev https://github.com/satisfactorymodding/SatisfactoryModLoader.git ${{env.SML_DIR}} } - name: Pull Wwise Project run: | if (!(Test-Path "${{env.SML_DIR}}/SML_WwiseProject" -PathType Container)) { git clone --branch main git@10.10.10.14:RefinedRD/WwiseProject.git "${{env.SML_DIR}}/SML_WwiseProject" } cd ${{env.SML_DIR}}/SML_WwiseProject git fetch --all git reset --hard origin/main git lfs fetch --all git lfs pull git lfs checkout $wwiseConsole = "C:/Program Files (x86)/Audiokinetic/Wwise2023.1.14.8770/Authoring/x64/Release/bin/WwiseConsole.exe" if (!(Test-Path $wwiseConsole)) { Write-Error "WwiseConsole not found at $wwiseConsole" exit 1 } & $wwiseConsole generate-soundbank "${{env.SML_DIR}}/SML_WwiseProject/SML_WwiseProject.wproj" --platform Windows Mac --verbose echo "Done" - name: Pull Mods run: | $modPath = "${{env.SML_DIR}}/Mods/${{env.MOD_NAME}}" $repoName = "sf_mod_${{env.MOD_NAME}}" if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/${{env.MOD_NAME}}" } if (!(Test-Path $modPath -PathType Container)) { git clone git@10.10.10.14:RefinedRD/$repoName.git $modPath } cd $modPath $ref = "${{gitea.ref_name}}" git fetch --all --tags if (git rev-parse --verify --quiet "refs/tags/$ref") { git reset --hard $ref } else { git reset --hard "origin/$ref" } echo "Pulled ${{env.MOD_NAME}} @ latest (${{gitea.ref_name}})" - name: Generate Changelog id: changelog run: | $modPath = "${{env.SML_DIR}}/Mods/${{env.MOD_NAME}}" if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/${{env.MOD_NAME}}" } # Last commit that was actually released to SMR is marked by a release/* tag # pushed by the SMRDeploy job. No manual tagging, no manual changelog. $prevTag = (git -C $modPath describe --tags --abbrev=0 --match "release/*" HEAD 2>$null) if ($LASTEXITCODE -ne 0 -or [string]::IsNullOrWhiteSpace($prevTag)) { $prevTag = $null $range = "HEAD" echo "No previous release/* tag found - using full history" } else { $range = "$prevTag..HEAD" echo "Previous release tag: $prevTag" } $subjects = @(git -C $modPath log --no-merges --pretty=format:%s $range) | Where-Object { -not [string]::IsNullOrWhiteSpace($_) } $groups = [ordered]@{ "Features" = @() "Fixes" = @() "Performance" = @() "Changes" = @() "Other" = @() } # Commit types that are noise for players - never shown $skip = @("chore", "ci", "docs", "test", "tests", "style", "build") foreach ($subject in $subjects) { if ($subject -match '^(?[a-zA-Z]+)(\([^)]*\))?!?:\s*(?.+)$') { $type = $matches.type.ToLower() $desc = $matches.desc.Trim() if ($skip -contains $type) { continue } switch ($type) { "feat" { $groups["Features"] += $desc } "fix" { $groups["Fixes"] += $desc } "perf" { $groups["Performance"] += $desc } "refactor" { $groups["Changes"] += $desc } default { $groups["Other"] += $desc } } } else { $groups["Other"] += $subject.Trim() } } $lines = @() foreach ($name in $groups.Keys) { $items = $groups[$name] | Select-Object -Unique if ($items.Count -eq 0) { continue } $lines += "### $name" foreach ($item in $items) { $lines += "- $item" } $lines += "" } if ($lines.Count -eq 0) { $lines = @("### Changes", "- Maintenance release") } $header = @("# Change Log - v${{steps.version.outputs.version}}", "") $changelog = (($header + $lines) -join "`n").Trim() echo "----- Changelog -----" echo $changelog echo "---------------------" # base64 so the multiline markdown survives job outputs intact $b64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($changelog)) Write-Output "changelog_b64=$b64" >> $Env:GITHUB_OUTPUT - name: Update UPlugin Versions run: | $newVersion = "${{steps.version.outputs.version}}" $mod = "${{env.MOD_NAME}}" $modPath = "${{env.SML_DIR}}/Mods/$mod" if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/$mod" } $upluginPath = "$modPath/$mod.uplugin" $UPlugin = (Get-Content $upluginPath | ConvertFrom-Json) $majorVersion = [int]($newVersion -split '\.')[0] $UPlugin.Version = $majorVersion $UPlugin.SemVersion = $newVersion $UPlugin.VersionName = $newVersion echo "Set $mod version to $newVersion (Version=$majorVersion)" ($UPlugin | ConvertTo-Json -Depth 100) -replace '\\u0026', '&' | Set-Content $upluginPath - name: Compile Editor run: | $buildTool = "${{env.ENGINE_DIR}}/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" cd ${{env.SML_DIR}} & $buildTool -projectfiles -project="${{env.SML_DIR}}/FactoryGame.uproject" -game -rocket -progress & $buildTool Development Win64 -project="${{env.SML_DIR}}/FactoryGame.uproject" -TargetType="Editor" -progress - name: Build Mods run: | $newVersion = "${{steps.version.outputs.version}}" if (!(Test-Path ${{env.BUILT_MODS_DIR}})) { New-Item -ItemType Directory -Force -Path ${{env.BUILT_MODS_DIR}} } $mod = "${{env.MOD_NAME}}" if (Test-Path "${{env.SML_DIR}}/Saved/ArchivedPlugins/$mod") { Remove-Item -Recurse "${{env.SML_DIR}}/Saved/ArchivedPlugins/$mod" } if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/$mod" }else { $modPath = "${{env.SML_DIR}}/Mods/$mod" } $version = $newVersion & "${{env.ENGINE_DIR}}/Engine/Build/BatchFiles/RunUAT.bat" ` -ScriptsForProject="${{env.SML_DIR}}/FactoryGame.uproject" ` PackagePlugin ` -Project="${{env.SML_DIR}}/FactoryGame.uproject" ` -dlcname="$mod" ` -build -server ` -clientconfig=Shipping -serverconfig=Shipping ` -platform=Win64 -serverplatform=Win64+Linux ` -nocompileeditor -installed -merge Copy-Item "${{env.SML_DIR}}/Saved/ArchivedPlugins/$mod/$mod.zip" "${{env.BUILT_MODS_DIR}}/$mod.$version.zip" -Force echo "Done $mod @ $version" - name: Publish Built Version run: | $version = "${{steps.version.outputs.version}}" $modPath = "${{env.SML_DIR}}/Mods/${{env.MOD_NAME}}" if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/${{env.MOD_NAME}}" } $commit = (git -C $modPath rev-parse HEAD) $body = "{`"version`":`"$version`",`"commit`":`"$commit`"}" curl -s -X POST ` -H "x-rp-key: ${{secrets.RRD_API_KEY}}" ` -H "Content-Type: application/json" ` -d $body ` "${{secrets.RRD_API_URL}}/api/v1/mods/version/${{env.MOD_NAME}}" echo "" echo "Published ${{env.MOD_NAME}} @ $version ($commit)" - uses: actions/upload-artifact@v3 with: name: built-mods path: | ${{env.BUILT_MODS_DIR}}/*.zip ${{env.BUILT_MODS_DIR}}/Install-DevBuild.ps1 overwrite: true SMRDeploy: if: ${{ vars.DEPLOY == 'true' }} needs: Build runs-on: windows-ue defaults: run: shell: pwsh steps: - name: Download artifact uses: actions/download-artifact@v3 with: name: built-mods path: ${{env.BUILT_MODS_DIR}} - name: Deploy to SMR id: deploy run: | echo "Deploying to SMR" $Version = "${{needs.Build.outputs.version}}" $Changelog = [Text.Encoding]::UTF8.GetString([Convert]::FromBase64String("${{needs.Build.outputs.changelog_b64}}")) echo "Changelog:" echo $Changelog $query = '{ "query": "query { getModByReference(modReference:\"${{env.MOD_NAME}}\"){ versions(filter:{limit: 1}){ version } }}"}' $SMRVersion = (Invoke-RestMethod ` -Method POST ` -Uri "https://api.ficsit.app/v2/query" ` -Body $query ` -ContentType "application/json").data.getModByReference.versions[0].version if ($Version -eq $SMRVersion) { echo "SMR Mod Version Already Exists.. Skip" exit 0 } $File = (Get-ChildItem "${{env.BUILT_MODS_DIR}}/${{env.MOD_NAME}}*").FullName $APIURL = "https://api.ficsit.app" Write-Host "Uploading $File to $APIURL" & "S:/ficsit_windows_amd64.exe" smr upload ` --api-base "$APIURL" ` --api-key "${{secrets.FICSIT_TOKEN}}" ` "${{env.MOD_ID}}" "$File" "$Changelog" if ($LASTEXITCODE -ne 0) { Write-Error "SMR upload failed" exit 1 } Write-Output "uploaded=true" >> $Env:GITHUB_OUTPUT echo "Done" - name: Tag Released Commit if: ${{ steps.deploy.outputs.uploaded == 'true' }} run: | $Version = "${{needs.Build.outputs.version}}" $modPath = "${{env.SML_DIR}}/Mods/${{env.MOD_NAME}}" if ("${{env.IS_GAME_FEATURE_PLUGIN}}" -eq "true") { $modPath = "${{env.SML_DIR}}/Mods/GameFeatures/${{env.MOD_NAME}}" } # This tag is the marker the next build's changelog starts from git -C $modPath tag -f "release/$Version" git -C $modPath push -f origin "release/$Version" echo "Tagged release/$Version @ $(git -C $modPath rev-parse HEAD)"