name: ASF-publish on: [push, pull_request] env: CONFIGURATION: Release DOTNET_CLI_TELEMETRY_OPTOUT: true DOTNET_NOLOGO: true DOTNET_SDK_VERSION: 8.0 NODE_JS_VERSION: 'lts/*' PLUGINS_BUNDLED: ArchiSteamFarm.OfficialPlugins.ItemsMatcher ArchiSteamFarm.OfficialPlugins.MobileAuthenticator ArchiSteamFarm.OfficialPlugins.SteamTokenDumper PLUGINS_INCLUDED: ArchiSteamFarm.OfficialPlugins.Monitoring # Apart from declaring them here, there is certain amount of hardcoding needed below for uploading permissions: {} jobs: publish-asf-ui: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4.1.7 with: show-progress: false submodules: recursive - name: Setup Node.js with npm uses: actions/setup-node@v4.0.3 with: check-latest: true node-version: ${{ env.NODE_JS_VERSION }} - name: Verify Node.js run: node -v - name: Verify npm run: npm -v - name: Install npm modules for ASF-ui run: npm ci --no-progress --prefix ASF-ui - name: Publish ASF-ui run: npm run-script deploy --no-progress --prefix ASF-ui - name: Upload ASF-ui uses: actions/upload-artifact@v4.3.4 with: if-no-files-found: error name: ASF-ui path: ASF-ui/dist publish-asf: needs: publish-asf-ui strategy: fail-fast: false matrix: include: - os: ubuntu-latest variant: generic - os: ubuntu-latest variant: linux-arm - os: ubuntu-latest variant: linux-arm64 - os: ubuntu-latest variant: linux-x64 - os: macos-latest variant: osx-arm64 - os: macos-latest variant: osx-x64 - os: windows-latest variant: win-arm64 - os: windows-latest variant: win-x64 environment: build runs-on: ${{ matrix.os }} permissions: attestations: write id-token: write steps: - name: Checkout code uses: actions/checkout@v4.1.7 with: show-progress: false - name: Setup .NET Core uses: actions/setup-dotnet@v4.0.1 with: dotnet-version: ${{ env.DOTNET_SDK_VERSION }} - name: Verify .NET Core run: dotnet --info - name: Download previously built ASF-ui uses: actions/download-artifact@v4.1.8 with: name: ASF-ui path: ASF-ui/dist - name: Prepare private key for signing on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: ASF_PRIVATE_SNK: ${{ secrets.ASF_PRIVATE_SNK }} shell: sh run: | set -eu if [ -n "${ASF_PRIVATE_SNK-}" ]; then echo "$ASF_PRIVATE_SNK" | base64 -d > "resources/ArchiSteamFarm.snk" fi - name: Prepare private key for signing on Windows if: startsWith(matrix.os, 'windows-') env: ASF_PRIVATE_SNK: ${{ secrets.ASF_PRIVATE_SNK }} shell: pwsh run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' if ((Test-Path env:ASF_PRIVATE_SNK) -and ($env:ASF_PRIVATE_SNK)) { echo "$env:ASF_PRIVATE_SNK" > "resources\ArchiSteamFarm.snk" certutil -f -decode "resources\ArchiSteamFarm.snk" "resources\ArchiSteamFarm.snk" if ($LastExitCode -ne 0) { throw "Last command failed." } } - name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: STEAM_TOKEN_DUMPER_TOKEN: ${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }} shell: sh run: | set -eu if [ -n "${STEAM_TOKEN_DUMPER_TOKEN-}" ] && [ -f "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SharedInfo.cs" ]; then sed "s/STEAM_TOKEN_DUMPER_TOKEN/${STEAM_TOKEN_DUMPER_TOKEN}/g" "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SharedInfo.cs" > "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SharedInfo.cs.new" mv "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SharedInfo.cs.new" "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper/SharedInfo.cs" fi - name: Prepare ArchiSteamFarm.OfficialPlugins.SteamTokenDumper on Windows if: startsWith(matrix.os, 'windows-') env: STEAM_TOKEN_DUMPER_TOKEN: ${{ secrets.STEAM_TOKEN_DUMPER_TOKEN }} shell: pwsh run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' if ((Test-Path env:STEAM_TOKEN_DUMPER_TOKEN) -and ($env:STEAM_TOKEN_DUMPER_TOKEN) -and (Test-Path "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper\SharedInfo.cs" -PathType Leaf)) { (Get-Content "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper\SharedInfo.cs").Replace('STEAM_TOKEN_DUMPER_TOKEN', "$env:STEAM_TOKEN_DUMPER_TOKEN") | Set-Content "ArchiSteamFarm.OfficialPlugins.SteamTokenDumper\SharedInfo.cs" } - name: Publish ASF-${{ matrix.variant }} on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: VARIANT: ${{ matrix.variant }} shell: bash run: | set -euo pipefail if [ "$VARIANT" = 'generic' ]; then variantArgs="-p:TargetLatestRuntimePatch=false -p:UseAppHost=false" else variantArgs="-p:PublishSingleFile=true -p:PublishTrimmed=true -r $VARIANT --self-contained" fi dotnet publish ArchiSteamFarm -c "$CONFIGURATION" -o "out/${VARIANT}" "-p:ASFVariant=${VARIANT}" -p:ContinuousIntegrationBuild=true --nologo $variantArgs # Include .ico file for all platforms, since only Windows script can bundle it inside the exe cp "resources/ASF.ico" "out/${VARIANT}/ArchiSteamFarm.ico" # Include extra logic for builds marked for release case "$GITHUB_REF" in "refs/tags/"*) # Update link in Changelog.html accordingly if [ -f "out/${VARIANT}/Changelog.html" ]; then tag="$(echo "$GITHUB_REF" | cut -c 11-)" sed "s/ArchiSteamFarm\/commits\/main/ArchiSteamFarm\/releases\/tag\/${tag}/g" "out/${VARIANT}/Changelog.html" > "out/${VARIANT}/Changelog.html.new" mv "out/${VARIANT}/Changelog.html.new" "out/${VARIANT}/Changelog.html" fi ;; esac - name: Publish ASF-${{ matrix.variant }} on Windows if: startsWith(matrix.os, 'windows-') env: VARIANT: ${{ matrix.variant }} shell: pwsh run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' if ($env:VARIANT -like 'generic*') { $variantArgs = '-p:TargetLatestRuntimePatch=false', '-p:UseAppHost=false' } else { $variantArgs = '-p:PublishSingleFile=true', '-p:PublishTrimmed=true', '-r', "$env:VARIANT", '--self-contained' } dotnet publish ArchiSteamFarm -c "$env:CONFIGURATION" -o "out\$env:VARIANT" "-p:ASFVariant=$env:VARIANT" -p:ContinuousIntegrationBuild=true --nologo $variantArgs if ($LastExitCode -ne 0) { throw "Last command failed." } # Icon is available only in .exe Windows builds, we'll bundle the .ico file for other flavours if (!(Test-Path "out\$env:VARIANT\ArchiSteamFarm.exe" -PathType Leaf)) { Copy-Item 'resources\ASF.ico' "out\$env:VARIANT\ArchiSteamFarm.ico" } # Include extra logic for builds marked for release if ($env:GITHUB_REF -like 'refs/tags/*') { # Update link in Changelog.html accordingly if (Test-Path "out\$env:VARIANT\Changelog.html" -PathType Leaf) { $tag = $env:GITHUB_REF.Substring(10) (Get-Content "out\$env:VARIANT\Changelog.html").Replace('ArchiSteamFarm/commits/main', "ArchiSteamFarm/releases/tag/$tag") | Set-Content "out\$env:VARIANT\Changelog.html" } } - name: Publish bundled plugins on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: VARIANT: ${{ matrix.variant }} shell: bash run: | set -euo pipefail if [ "$VARIANT" = 'generic' ]; then variantArgs="-p:TargetLatestRuntimePatch=false -p:UseAppHost=false" else variantArgs="-r $VARIANT" fi for plugin in $PLUGINS_BUNDLED; do dotnet publish "$plugin" -c "$CONFIGURATION" -o "out/${VARIANT}/plugins/${plugin}" "-p:ASFVariant=${VARIANT}" -p:ContinuousIntegrationBuild=true --nologo $variantArgs done - name: Publish bundled plugins on Windows if: startsWith(matrix.os, 'windows-') env: VARIANT: ${{ matrix.variant }} shell: pwsh run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' if ($env:VARIANT -like 'generic*') { $variantArgs = '-p:TargetLatestRuntimePatch=false', '-p:UseAppHost=false' } else { $variantArgs = '-r', "$env:VARIANT" } foreach ($plugin in $env:PLUGINS_BUNDLED.Split([char[]] $null, [System.StringSplitOptions]::RemoveEmptyEntries)) { dotnet publish "$plugin" -c "$env:CONFIGURATION" -o "out\$env:VARIANT\plugins\$plugin" "-p:ASFVariant=$env:VARIANT" -p:ContinuousIntegrationBuild=true --nologo $variantArgs if ($LastExitCode -ne 0) { throw "Last command failed." } } - name: Zip ASF-${{ matrix.variant }} on Unix if: startsWith(matrix.os, 'macos-') || startsWith(matrix.os, 'ubuntu-') env: VARIANT: ${{ matrix.variant }} shell: bash run: | set -euo pipefail # By default use fastest compression seven_zip_args="-mx=1" zip_args="-1" # Tweak compression args for release publishing case "$GITHUB_REF" in "refs/tags/"*) seven_zip_args="-mx=9 -mfb=258 -mpass=15" zip_args="-9" ;; esac # Create the final zip file case "$(uname -s)" in "Darwin") # We prefer to use zip on macOS as 7z implementation on that OS doesn't handle file permissions (chmod +x) if command -v zip >/dev/null; then ( cd "${GITHUB_WORKSPACE}/out/${VARIANT}" zip -q -r $zip_args "../ASF-${VARIANT}.zip" . ) else 7z a -bd -slp -tzip -mm=Deflate $seven_zip_args "out/ASF-${VARIANT}.zip" "${GITHUB_WORKSPACE}/out/${VARIANT}/*" fi ;; *) if command -v 7z >/dev/null; then 7z a -bd -slp -tzip -mm=Deflate $seven_zip_args "out/ASF-${VARIANT}.zip" "${GITHUB_WORKSPACE}/out/${VARIANT}/*" else ( cd "${GITHUB_WORKSPACE}/out/${VARIANT}" zip -q -r $zip_args "../ASF-${VARIANT}.zip" . ) fi ;; esac - name: Zip ASF-${{ matrix.variant }} on Windows if: startsWith(matrix.os, 'windows-') env: VARIANT: ${{ matrix.variant }} shell: pwsh run: | Set-StrictMode -Version Latest $ErrorActionPreference = 'Stop' $ProgressPreference = 'SilentlyContinue' # By default use fastest compression $compressionArgs = '-mx=1' # Tweak compression args for release publishing if ($env:GITHUB_REF -like 'refs/tags/*') { $compressionArgs = '-mx=9', '-mfb=258', '-mpass=15' } # Create the final zip file 7z a -bd -slp -tzip -mm=Deflate $compressionArgs "out\ASF-$env:VARIANT.zip" "$env:GITHUB_WORKSPACE\out\$env:VARIANT\*" if ($LastExitCode -ne 0) { throw "Last command failed." } # We can aid non-windows users by adding chmod +x flag to appropriate executables directly in the zip file # This is ALMOST a hack, but works reliably enough if (Test-Path "tools\zip_exec\zip_exec.exe" -PathType Leaf) { $executableFiles = @() if ($env:VARIANT -like 'generic*') { $executableFiles += 'ArchiSteamFarm.sh', 'ArchiSteamFarm-Service.sh' } elseif (($env:VARIANT -like 'linux*') -or ($env:VARIANT -like 'osx*')) { $executableFiles += 'ArchiSteamFarm', 'ArchiSteamFarm-Service.sh' } foreach ($executableFile in $executableFiles) { tools\zip_exec\zip_exec.exe "out\ASF-$env:VARIANT.zip" "$executableFile" if ($LastExitCode -ne 0) { throw "Last command failed." } } } - name: Generate artifact attestation for ASF-${{ matrix.variant }}.zip if: ${{ github.event_name == 'push' }} uses: actions/attest-build-provenance@v1.3.3 with: subject-path: out/ASF-${{ matrix.variant }}.zip - name: Upload ASF-${{ matrix.variant }} uses: actions/upload-artifact@v4.3.4 with: if-no-files-found: error name: ${{ matrix.os }}_ASF-${{ matrix.variant }} path: out/ASF-${{ matrix.variant }}.zip - name: Publish included plugins on Unix if: ${{ matrix.os == 'ubuntu-latest' && matrix.variant == 'generic' }} env: VARIANT: ${{ matrix.variant }} shell: bash run: | set -euo pipefail # By default use fastest compression seven_zip_args="-mx=1" zip_args="-1" # Tweak compression args for release publishing case "$GITHUB_REF" in "refs/tags/"*) seven_zip_args="-mx=9 -mfb=258 -mpass=15" zip_args="-9" ;; esac for plugin in $PLUGINS_INCLUDED; do dotnet publish "$plugin" -c "$CONFIGURATION" -o "out/${plugin}" "-p:ASFVariant=${VARIANT}" -p:ContinuousIntegrationBuild=true -p:TargetLatestRuntimePatch=false -p:UseAppHost=false --nologo # Create the final zip file if command -v 7z >/dev/null; then 7z a -bd -slp -tzip -mm=Deflate $seven_zip_args "out/${plugin}.zip" "${GITHUB_WORKSPACE}/out/${plugin}/*" else ( cd "${GITHUB_WORKSPACE}/out/${plugin}" zip -q -r $zip_args "../${plugin}.zip" . ) fi done - name: Generate artifact attestation for ArchiSteamFarm.OfficialPlugins.Monitoring if: ${{ github.event_name == 'push' && matrix.os == 'ubuntu-latest' && matrix.variant == 'generic' }} uses: actions/attest-build-provenance@v1.3.3 with: subject-path: out/ArchiSteamFarm.OfficialPlugins.Monitoring.zip - name: Upload ArchiSteamFarm.OfficialPlugins.Monitoring if: ${{ matrix.os == 'ubuntu-latest' && matrix.variant == 'generic' }} uses: actions/upload-artifact@v4.3.4 with: if-no-files-found: error name: ArchiSteamFarm.OfficialPlugins.Monitoring path: out/ArchiSteamFarm.OfficialPlugins.Monitoring.zip release: if: ${{ github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') }} needs: publish-asf environment: release-github runs-on: ubuntu-latest permissions: attestations: write contents: write id-token: write steps: - name: Checkout code uses: actions/checkout@v4.1.7 with: show-progress: false - name: Download ASF-generic artifact from ubuntu-latest uses: actions/download-artifact@v4.1.8 with: name: ubuntu-latest_ASF-generic path: out - name: Download ASF-linux-arm artifact from ubuntu-latest uses: actions/download-artifact@v4.1.8 with: name: ubuntu-latest_ASF-linux-arm path: out - name: Download ASF-linux-arm64 artifact from ubuntu-latest uses: actions/download-artifact@v4.1.8 with: name: ubuntu-latest_ASF-linux-arm64 path: out - name: Download ASF-linux-x64 artifact from ubuntu-latest uses: actions/download-artifact@v4.1.8 with: name: ubuntu-latest_ASF-linux-x64 path: out - name: Download ASF-osx-arm64 artifact from macos-latest uses: actions/download-artifact@v4.1.8 with: name: macos-latest_ASF-osx-arm64 path: out - name: Download ASF-osx-x64 artifact from macos-latest uses: actions/download-artifact@v4.1.8 with: name: macos-latest_ASF-osx-x64 path: out - name: Download ASF-win-arm64 artifact from windows-latest uses: actions/download-artifact@v4.1.8 with: name: windows-latest_ASF-win-arm64 path: out - name: Download ASF-win-x64 artifact from windows-latest uses: actions/download-artifact@v4.1.8 with: name: windows-latest_ASF-win-x64 path: out - name: Download ArchiSteamFarm.OfficialPlugins.Monitoring artifact uses: actions/download-artifact@v4.1.8 with: name: ArchiSteamFarm.OfficialPlugins.Monitoring path: out - name: Import GPG key for signing uses: crazy-max/ghaction-import-gpg@v6.1.0 with: gpg_private_key: ${{ secrets.ARCHIBOT_GPG_PRIVATE_KEY }} - name: Generate SHA-512 checksums and signature shell: sh working-directory: out run: | set -eu sha512sum *.zip > SHA512SUMS gpg -a -b -o SHA512SUMS.sign SHA512SUMS - name: Generate artifact attestation for SHA512SUMS uses: actions/attest-build-provenance@v1.3.3 with: subject-path: out/SHA512SUMS - name: Upload SHA512SUMS uses: actions/upload-artifact@v4.3.4 with: if-no-files-found: error name: SHA512SUMS path: out/SHA512SUMS - name: Generate artifact attestation for SHA512SUMS.sign uses: actions/attest-build-provenance@v1.3.3 with: subject-path: out/SHA512SUMS.sign - name: Upload SHA512SUMS.sign uses: actions/upload-artifact@v4.3.4 with: if-no-files-found: error name: SHA512SUMS.sign path: out/SHA512SUMS.sign - name: Create ArchiSteamFarm GitHub release uses: ncipollo/release-action@v1.14.0 with: allowUpdates: true artifactErrorsFailBuild: true artifacts: "out/*" bodyFile: .github/RELEASE_TEMPLATE.md makeLatest: false name: ArchiSteamFarm V${{ github.ref_name }} prerelease: true token: ${{ secrets.ARCHIBOT_GITHUB_TOKEN }} updateOnlyUnreleased: true