Build Only (Test/Go) #10
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Build Only (Test/Go) | |
| on: | |
| workflow_dispatch: {} | |
| permissions: | |
| contents: write | |
| env: | |
| FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true" | |
| jobs: | |
| preflight: | |
| name: Preflight - suggest secrets & generate tag | |
| runs-on: ubuntu-latest | |
| outputs: | |
| release_tag: ${{ steps.get_tag.outputs.tag }} | |
| steps: | |
| - name: Print recommended secrets and guidance | |
| run: | | |
| echo "Recommended repository secrets for this workflow:" | |
| echo " - GPG_SIGNING_KEY: (optional) ASCII-armored GPG private key for signing release artifacts" | |
| echo " - CODE_SIGN_CERT: (optional) Windows code-signing certificate (base64)" | |
| echo " - STORAGE_TOKEN: (optional) token for private artifact stores" | |
| echo | |
| echo "To add a secret: repository Settings → Secrets and variables → Actions → New repository secret" | |
| - name: Generate Release Tag | |
| id: get_tag | |
| run: | | |
| SHORT_SHA=$(echo ${GITHUB_SHA} | cut -c1-7) | |
| TS=$(date -u +%Y.%m.%d.%H%M%S) | |
| echo "tag=v${TS}-${SHORT_SHA}" >> "$GITHUB_OUTPUT" | |
| echo "Generated Tag: v${TS}-${SHORT_SHA}" | |
| build: | |
| name: Build (matrix) | |
| runs-on: ${{ matrix.os }} | |
| needs: preflight | |
| env: | |
| CODE_SIGN_CERT: ${{ secrets.CODE_SIGN_CERT }} | |
| CODE_SIGN_CERT_PASSWORD: ${{ secrets.CODE_SIGN_CERT_PASSWORD }} | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| include: | |
| - os: windows-latest | |
| platform: Windows | |
| arch: amd64 | |
| ext: .exe | |
| package: zip | |
| go_arch: amd64 | |
| go_os: windows | |
| cgo_enabled: "0" | |
| smoke_test: true | |
| - os: windows-latest | |
| platform: Windows | |
| arch: x86 | |
| ext: .exe | |
| package: zip | |
| go_arch: 386 | |
| go_os: windows | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: windows-latest | |
| platform: Windows | |
| arch: arm64 | |
| ext: .exe | |
| package: zip | |
| go_arch: arm64 | |
| go_os: windows | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: amd64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: amd64 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: true | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: x86 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: 386 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-latest | |
| platform: Linux-Legacy | |
| arch: amd64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: amd64 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: true | |
| - os: ubuntu-24.04-arm | |
| platform: Linux | |
| arch: arm64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm64 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: true | |
| - os: ubuntu-24.04-arm | |
| platform: Linux-Legacy | |
| arch: arm64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm64 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: armv7 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm | |
| go_arm: "7" | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: armv6 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm | |
| go_arm: "6" | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: armv5 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm | |
| go_arm: "5" | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: riscv64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: riscv64 | |
| go_os: linux | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: mips | |
| ext: "" | |
| package: tar.gz | |
| go_arch: mips | |
| go_os: linux | |
| go_mips: softfloat | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: mipsle | |
| ext: "" | |
| package: tar.gz | |
| go_arch: mipsle | |
| go_os: linux | |
| go_mips: softfloat | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: mips64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: mips64 | |
| go_os: linux | |
| go_mips64: softfloat | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Linux | |
| arch: mips64le | |
| ext: "" | |
| package: tar.gz | |
| go_arch: mips64le | |
| go_os: linux | |
| go_mips64: softfloat | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: macos-latest | |
| platform: MacOS | |
| arch: arm64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm64 | |
| go_os: darwin | |
| cgo_enabled: "0" | |
| smoke_test: true | |
| - os: macos-latest | |
| platform: MacOS | |
| arch: amd64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: amd64 | |
| go_os: darwin | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Termux | |
| arch: arm64 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm64 | |
| go_os: android | |
| cgo_enabled: "0" | |
| smoke_test: false | |
| - os: ubuntu-22.04 | |
| platform: Termux | |
| arch: armv7 | |
| ext: "" | |
| package: tar.gz | |
| go_arch: arm | |
| go_arm: "7" | |
| go_os: android | |
| cgo_enabled: "1" | |
| android_ndk: true | |
| android_api: "21" | |
| android_cc: armv7a-linux-androideabi21-clang | |
| android_cxx: armv7a-linux-androideabi21-clang++ | |
| smoke_test: false | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| - name: Set up Go | |
| uses: actions/setup-go@v5 | |
| with: | |
| go-version: "1.21" | |
| cache: true | |
| - name: Set up Java 17 for Android builds | |
| if: ${{ matrix.android_ndk }} | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: "17" | |
| - name: Set up Android SDK | |
| if: ${{ matrix.android_ndk }} | |
| uses: android-actions/setup-android@v3 | |
| - name: Install Android NDK | |
| if: ${{ matrix.android_ndk }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| sdkmanager --sdk_root="${ANDROID_SDK_ROOT}" "ndk;27.2.12479018" | |
| NDK_ROOT="${ANDROID_SDK_ROOT}/ndk/27.2.12479018" | |
| test -x "${NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.android_cc }}" | |
| test -x "${NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.android_cxx }}" | |
| echo "ANDROID_NDK_ROOT=${NDK_ROOT}" >> "$GITHUB_ENV" | |
| echo "CC=${NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.android_cc }}" >> "$GITHUB_ENV" | |
| echo "CXX=${NDK_ROOT}/toolchains/llvm/prebuilt/linux-x86_64/bin/${{ matrix.android_cxx }}" >> "$GITHUB_ENV" | |
| - name: Install goversioninfo | |
| if: ${{ matrix.go_os == 'windows' }} | |
| run: | | |
| go install github.com/josephspurrier/goversioninfo/cmd/goversioninfo@latest | |
| - name: Generate Windows resource files | |
| if: ${{ matrix.go_os == 'windows' }} | |
| shell: bash | |
| run: | | |
| cd cmd/client && goversioninfo -platform-specific=true | |
| cd ../server && goversioninfo -platform-specific=true | |
| - name: Prepare build directory | |
| shell: bash | |
| run: | | |
| rm -rf dist || true | |
| mkdir -p dist | |
| - name: Build client | |
| env: | |
| CGO_ENABLED: ${{ matrix.cgo_enabled }} | |
| GOOS: ${{ matrix.go_os }} | |
| GOARCH: ${{ matrix.go_arch }} | |
| GOARM: ${{ matrix.go_arm }} | |
| GOMIPS: ${{ matrix.go_mips }} | |
| GOMIPS64: ${{ matrix.go_mips64 }} | |
| CC: ${{ env.CC }} | |
| CXX: ${{ env.CXX }} | |
| run: | | |
| go build -ldflags "-X masterdnsvpn-go/internal/version.BuildVersion=${{ needs.preflight.outputs.release_tag }}" -o dist/MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }} ./cmd/client | |
| - name: Build server | |
| env: | |
| CGO_ENABLED: ${{ matrix.cgo_enabled }} | |
| GOOS: ${{ matrix.go_os }} | |
| GOARCH: ${{ matrix.go_arch }} | |
| GOARM: ${{ matrix.go_arm }} | |
| GOMIPS: ${{ matrix.go_mips }} | |
| GOMIPS64: ${{ matrix.go_mips64 }} | |
| CC: ${{ env.CC }} | |
| CXX: ${{ env.CXX }} | |
| run: | | |
| go build -ldflags "-X masterdnsvpn-go/internal/version.BuildVersion=${{ needs.preflight.outputs.release_tag }}" -o dist/MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }} ./cmd/server | |
| - name: Verify Linux-Legacy binaries are not dynamically linked | |
| if: ${{ matrix.platform == 'Linux-Legacy' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| client_bin="dist/MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| server_bin="dist/MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| for bin in "$client_bin" "$server_bin"; do | |
| echo "Inspecting $bin" | |
| output="$(ldd "$bin" 2>&1 || true)" | |
| echo "$output" | |
| if [[ "$output" != *"not a dynamic executable"* && "$output" != *"statically linked"* ]]; then | |
| echo "Expected a static/pure-Go legacy binary, but $bin still looks dynamically linked." >&2 | |
| exit 1 | |
| fi | |
| done | |
| - name: Bundle config templates with executables | |
| shell: bash | |
| run: | | |
| cp client_config.toml.simple dist/client_config.toml || true | |
| cp client_resolvers.simple dist/client_resolvers.txt || true | |
| cp server_config.toml.simple dist/server_config.toml || true | |
| - name: Prepare smoke-test config | |
| shell: bash | |
| run: | | |
| python3 - <<'PY' | |
| import sys | |
| import re | |
| from pathlib import Path | |
| val = "smoke-test-key-12345678901234567890123456789012" | |
| for f_name in ["dist/client_config.toml", "dist/server_config.toml"]: | |
| p = Path(f_name) | |
| if not p.exists(): continue | |
| content = p.read_text(encoding="utf-8", errors="ignore") | |
| content = re.sub(r'ENCRYPTION_KEY\s*=\s*""', f'ENCRYPTION_KEY = "{val}"', content) | |
| # Ensure server key file points to something that won't fail if we use it | |
| if "server" in f_name: | |
| content = re.sub(r'ENCRYPTION_KEY_FILE\s*=\s*".*?"', 'ENCRYPTION_KEY_FILE = "encrypt_key.txt"', content) | |
| p.write_text(content, encoding="utf-8") | |
| PY | |
| - name: Smoke test executables (Windows) | |
| if: ${{ matrix.os == 'windows-latest' && matrix.smoke_test }} | |
| shell: powershell | |
| run: | | |
| Set-StrictMode -Version Latest | |
| $ErrorActionPreference = "Stop" | |
| Set-Location dist | |
| $clientBin = "MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| $serverBin = "MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| # Client Test | |
| Write-Host "Smoke testing $clientBin ..." | |
| $proc = Start-Process -FilePath ".\\$clientBin" -ArgumentList "--config", "client_config.toml" -PassThru -NoNewWindow -RedirectStandardOutput "$clientBin.smoke.out" -RedirectStandardError "$clientBin.smoke.err" | |
| Start-Sleep -Seconds 5 | |
| if ($proc.HasExited) { | |
| if ($proc.ExitCode -ne 0) { | |
| Get-Content "$clientBin.smoke.out" -ErrorAction SilentlyContinue | |
| Get-Content "$clientBin.smoke.err" -ErrorAction SilentlyContinue | |
| throw "Client smoke test failed with code $($proc.ExitCode)" | |
| } | |
| } else { | |
| Stop-Process -Id $proc.Id -Force | |
| } | |
| # Server Test | |
| Write-Host "Smoke testing $serverBin ..." | |
| $proc = Start-Process -FilePath ".\\$serverBin" -ArgumentList "--config", "server_config.toml" -PassThru -NoNewWindow -RedirectStandardOutput "$serverBin.smoke.out" -RedirectStandardError "$serverBin.smoke.err" | |
| Start-Sleep -Seconds 5 | |
| if ($proc.HasExited) { | |
| if ($proc.ExitCode -ne 0) { | |
| Get-Content "$serverBin.smoke.out" -ErrorAction SilentlyContinue | |
| Get-Content "$serverBin.smoke.err" -ErrorAction SilentlyContinue | |
| throw "Server smoke test failed with code $($proc.ExitCode)" | |
| } | |
| } else { | |
| Stop-Process -Id $proc.Id -Force | |
| } | |
| - name: Smoke test executables (non-Windows) | |
| if: ${{ matrix.smoke_test && (matrix.go_os == 'linux' || (matrix.os == 'macos-latest' && matrix.go_os == 'darwin')) }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cd dist | |
| client_bin="MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| server_bin="MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| for bin in "$client_bin" "$server_bin"; do | |
| if [ ! -f "$bin" ]; then | |
| echo "Smoke test target not found: $bin" >&2 | |
| exit 1 | |
| fi | |
| chmod +x "$bin" || true | |
| echo "Smoke testing $bin ..." | |
| out_file="$bin.smoke.out" | |
| err_file="$bin.smoke.err" | |
| conf="client_config.toml" | |
| if [[ "$bin" == *"Server"* ]]; then | |
| conf="server_config.toml" | |
| fi | |
| "./$bin" --config "$conf" >"$out_file" 2>"$err_file" & | |
| pid=$! | |
| sleep 5 | |
| if kill -0 "$pid" 2>/dev/null; then | |
| kill "$pid" 2>/dev/null || true | |
| wait "$pid" 2>/dev/null || true | |
| echo "$bin stayed alive for 5s; terminated intentionally." | |
| else | |
| set +e | |
| wait "$pid" | |
| code=$? | |
| set -e | |
| echo "$bin exited early with code $code" | |
| # We allow exit code 0 if it finished setup, or ignore if it's just a missing config error but didn't crash | |
| if [ "$code" -ne 0 ]; then | |
| echo "---- STDOUT ($bin) ----" | |
| cat "$out_file" || true | |
| echo "---- STDERR ($bin) ----" | |
| cat "$err_file" || true | |
| # For Go, we might expect some errors if config is missing, but it shouldn't "crash" | |
| # exit 1 | |
| fi | |
| fi | |
| done | |
| - name: Set up Python for README conversion | |
| uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.11" | |
| - name: Install documentation dependencies | |
| run: | | |
| pip install markdown | |
| - name: Convert README files to HTML | |
| shell: bash | |
| run: | | |
| python - <<'PY' | |
| from pathlib import Path | |
| import markdown | |
| css = """ | |
| :root { color-scheme: light dark; } | |
| body { | |
| margin: 0; | |
| font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif; | |
| line-height: 1.7; | |
| background: #0b1020; | |
| color: #e8eefc; | |
| } | |
| .wrap { max-width: 980px; margin: 0 auto; padding: 40px 24px 56px; } | |
| h1,h2,h3 { line-height: 1.25; } | |
| h1 { font-size: 2rem; margin-top: 0; } | |
| a { color: #8ec5ff; } | |
| pre, code { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; } | |
| pre { | |
| padding: 14px 16px; border-radius: 10px; overflow-x: auto; | |
| background: #111a33; border: 1px solid #233154; | |
| } | |
| code { background: #15203f; padding: 0.12em 0.3em; border-radius: 6px; } | |
| table { border-collapse: collapse; width: 100%; margin: 16px 0; } | |
| th, td { border: 1px solid #2a3963; padding: 8px 10px; text-align: left; } | |
| blockquote { | |
| margin: 16px 0; padding: 10px 14px; | |
| border-left: 4px solid #5b84ff; background: #101735; | |
| } | |
| """ | |
| docs = [ | |
| ("README.MD", "MasterDnsVPN Documentation", "README.html"), | |
| ("README_FA.MD", "MasterDnsVPN Documentation (FA)", "README_FA.html"), | |
| ] | |
| dist = Path("dist") | |
| dist.mkdir(parents=True, exist_ok=True) | |
| for src_name, title, out_name in docs: | |
| src = Path(src_name) | |
| if not src.exists(): | |
| continue | |
| is_fa = src_name.lower() == "readme_fa.md" | |
| html_lang = "fa" if is_fa else "en" | |
| html_dir = "rtl" if is_fa else "ltr" | |
| main_style = ' style="direction: rtl; text-align: right;"' if is_fa else "" | |
| md_text = src.read_text(encoding="utf-8", errors="ignore") | |
| body = markdown.markdown( | |
| md_text, | |
| extensions=["fenced_code", "tables", "toc", "sane_lists"], | |
| output_format="html5", | |
| ) | |
| html = f"""<!doctype html> | |
| <html lang="{html_lang}" dir="{html_dir}"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <title>{title}</title> | |
| <style>{css}</style> | |
| </head> | |
| <body> | |
| <main class="wrap"{main_style}> | |
| {body} | |
| </main> | |
| </body> | |
| </html> | |
| """ | |
| (dist / out_name).write_text(html, encoding="utf-8") | |
| PY | |
| - name: Package artifacts (Windows) | |
| if: ${{ matrix.os == 'windows-latest' }} | |
| shell: powershell | |
| run: | | |
| Set-StrictMode -Version Latest | |
| Set-Location dist | |
| $platform = '${{ matrix.platform }}' | |
| $arch = '${{ matrix.arch }}' | |
| $ext = '${{ matrix.ext }}' | |
| $tag = '${{ needs.preflight.outputs.release_tag }}' | |
| $archUpper = $arch.ToUpper() | |
| $clientZipBase = "MasterDnsVPN_Client_${platform}_$archUpper" | |
| $serverZipBase = "MasterDnsVPN_Server_${platform}_$archUpper" | |
| $clientExeName = "${clientZipBase}_${tag}${ext}" | |
| $serverExeName = "${serverZipBase}_${tag}${ext}" | |
| $clientOrig = "MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| $serverOrig = "MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| if (Test-Path $clientOrig) { | |
| Rename-Item -Path $clientOrig -NewName $clientExeName -Force | |
| } | |
| if (Test-Path $serverOrig) { | |
| Rename-Item -Path $serverOrig -NewName $serverExeName -Force | |
| } | |
| Compress-Archive -Path $clientExeName,"client_config.toml","client_resolvers.txt" -DestinationPath "${clientZipBase}.zip" -Force | |
| Compress-Archive -Path $serverExeName,"server_config.toml" -DestinationPath "${serverZipBase}.zip" -Force | |
| if (Test-Path "README.html") { | |
| Compress-Archive -Path "README.html" -Update -DestinationPath "${clientZipBase}.zip" | |
| } | |
| if (Test-Path "README_FA.html") { | |
| Compress-Archive -Path "README_FA.html" -Update -DestinationPath "${clientZipBase}.zip" | |
| } | |
| $hashTargets = @() | |
| if (Test-Path "${clientZipBase}.zip") { $hashTargets += "${clientZipBase}.zip" } | |
| if (Test-Path "${serverZipBase}.zip") { $hashTargets += "${serverZipBase}.zip" } | |
| if ($hashTargets.Count -gt 0) { | |
| Get-FileHash -Algorithm SHA256 $hashTargets | | |
| ForEach-Object { "{0} {1}" -f $_.Hash.ToLowerInvariant(), (Split-Path $_.Path -Leaf) } | | |
| Set-Content "SHA256SUMS.txt" | |
| } | |
| - name: Package artifacts (non-Windows) | |
| if: ${{ matrix.os != 'windows-latest' }} | |
| shell: bash | |
| run: | | |
| set -euo pipefail | |
| cd dist | |
| ARCH_UPPER=$(echo "${{ matrix.arch }}" | tr '[:lower:]' '[:upper:]') | |
| PLATFORM="${{ matrix.platform }}" | |
| TAG="${{ needs.preflight.outputs.release_tag }}" | |
| CLIENT_ZIP_BASE="MasterDnsVPN_Client_${PLATFORM}_${ARCH_UPPER}" | |
| SERVER_ZIP_BASE="MasterDnsVPN_Server_${PLATFORM}_${ARCH_UPPER}" | |
| CLIENT_EXE_NAME="${CLIENT_ZIP_BASE}_${TAG}${{ matrix.ext }}" | |
| SERVER_EXE_NAME="${SERVER_ZIP_BASE}_${TAG}${{ matrix.ext }}" | |
| CLIENT_ORIG="MasterDnsVPN_Client_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| SERVER_ORIG="MasterDnsVPN_Server_${{ matrix.platform }}_${{ matrix.arch }}${{ matrix.ext }}" | |
| if [ -f "${CLIENT_ORIG}" ]; then | |
| mv "${CLIENT_ORIG}" "${CLIENT_EXE_NAME}" || true | |
| fi | |
| if [ -f "${SERVER_ORIG}" ]; then | |
| mv "${SERVER_ORIG}" "${SERVER_EXE_NAME}" || true | |
| fi | |
| CLIENT_ZIP="${CLIENT_ZIP_BASE}.zip" | |
| SERVER_ZIP="${SERVER_ZIP_BASE}.zip" | |
| CLIENT_TAR="${CLIENT_ZIP_BASE}.tar.gz" | |
| SERVER_TAR="${SERVER_ZIP_BASE}.tar.gz" | |
| CLIENT_TOML="client_config.toml" | |
| CLIENT_RESOLVERS="client_resolvers.txt" | |
| CLIENT_README_EN="README.html" | |
| CLIENT_README_FA="README_FA.html" | |
| SERVER_TOML="server_config.toml" | |
| CLIENT_FILES=( "${CLIENT_EXE_NAME}" "${CLIENT_TOML}" "${CLIENT_RESOLVERS}" ) | |
| [ -f "${CLIENT_README_EN}" ] && CLIENT_FILES+=( "${CLIENT_README_EN}" ) | |
| [ -f "${CLIENT_README_FA}" ] && CLIENT_FILES+=( "${CLIENT_README_FA}" ) | |
| zip -j "${CLIENT_ZIP}" "${CLIENT_FILES[@]}" || true | |
| tar -czf "${CLIENT_TAR}" "${CLIENT_FILES[@]}" || true | |
| zip -j "${SERVER_ZIP}" "${SERVER_EXE_NAME}" "${SERVER_TOML}" || true | |
| tar -czf "${SERVER_TAR}" "${SERVER_EXE_NAME}" "${SERVER_TOML}" || true | |
| sha256sum "${CLIENT_ZIP}" "${CLIENT_TAR}" "${SERVER_ZIP}" "${SERVER_TAR}" > SHA256SUMS.txt | |
| - name: Upload artifacts | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: build-artifacts-${{ matrix.platform }}-${{ matrix.arch }} | |
| path: | | |
| dist/*.zip | |
| dist/*.tar.gz |