name: OfficeCom Sentinel Client on: push: branches: - main tags: - "v*" workflow_dispatch: inputs: build_windows: description: "Build the Windows release package" required: false default: "false" jobs: validate-client: runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: "10.0.x" - name: Restore client run: dotnet restore ./src/OCSentinelCli/OCSentinelCli.csproj - name: Build client run: dotnet build ./src/OCSentinelCli/OCSentinelCli.csproj -c Release --no-restore build-client-windows: needs: validate-client # .NET can publish a self-contained Windows x64 client from Linux. # This keeps releases independent of a Windows Gitea runner. runs-on: ubuntu-22.04 steps: - name: Checkout uses: actions/checkout@v4 - name: Setup .NET uses: actions/setup-dotnet@v4 with: dotnet-version: "10.0.x" - name: Install PowerShell shell: bash run: | set -euo pipefail if command -v pwsh >/dev/null 2>&1; then pwsh --version exit 0 fi if [ "$(id -u)" -eq 0 ]; then SUDO="" elif command -v sudo >/dev/null 2>&1; then SUDO="sudo" else echo "PowerShell is missing and this runner cannot install packages." exit 1 fi . /etc/os-release case "$ID" in ubuntu) MICROSOFT_REPO="https://packages.microsoft.com/config/ubuntu/${VERSION_ID}/packages-microsoft-prod.deb" ;; debian) MICROSOFT_REPO="https://packages.microsoft.com/config/debian/${VERSION_ID}/packages-microsoft-prod.deb" ;; *) echo "Unsupported runner distribution: $ID"; exit 1 ;; esac $SUDO apt-get update $SUDO apt-get install -y ca-certificates curl curl -fsSL "$MICROSOFT_REPO" -o /tmp/packages-microsoft-prod.deb $SUDO dpkg -i /tmp/packages-microsoft-prod.deb $SUDO apt-get update $SUDO apt-get install -y powershell pwsh --version - name: Build client package shell: pwsh run: | ./build/build-client-package.ps1 - name: Build release manifest for tags shell: pwsh run: | $ref = if ($env:GITHUB_REF) { $env:GITHUB_REF } else { $env:GITEA_REF } $tag = if ($env:GITHUB_REF_NAME) { $env:GITHUB_REF_NAME } else { Split-Path -Leaf $ref } if ($tag -notlike "v*") { Write-Host "Not a version tag; skipping release manifest." exit 0 } $artifactUrl = "https://gitea.officecom.cloud/officecom/oc-sentinel/releases/download/$tag/OCSentinelClient-win-x64.zip" $channel = if ($tag -match '-beta(?:\.|$)') { 'beta' } else { 'stable' } ./build/build-release-manifest.ps1 -ArtifactUrl $artifactUrl -Channel $channel - name: Publish Gitea release assets shell: pwsh env: GITEA_TOKEN: ${{ secrets.RELEASE_TOKEN }} run: | $ref = if ($env:GITHUB_REF) { $env:GITHUB_REF } else { $env:GITEA_REF } $tag = if ($env:GITHUB_REF_NAME) { $env:GITHUB_REF_NAME } else { Split-Path -Leaf $ref } if ($tag -notlike "v*") { Write-Host "Not a version tag; skipping Gitea release publication." exit 0 } $headers = @{ Authorization = "token $env:GITEA_TOKEN" } $repository = if ($env:GITEA_REPOSITORY) { $env:GITEA_REPOSITORY } else { $env:GITHUB_REPOSITORY } $serverUrl = if ($env:GITEA_SERVER_URL) { $env:GITEA_SERVER_URL } else { $env:GITHUB_SERVER_URL } if ([string]::IsNullOrWhiteSpace($env:GITEA_TOKEN) -or [string]::IsNullOrWhiteSpace($repository) -or [string]::IsNullOrWhiteSpace($serverUrl)) { throw "Gitea release environment is incomplete. Expected GITEA_TOKEN, repository, and server URL." } $baseUrl = "$serverUrl/api/v1/repos/$repository" $releaseBody = @{ tag_name = $tag target_commitish = "${{ github.sha }}" name = "OfficeCom Sentinel $tag" body = "Automated OfficeCom Sentinel client release." } | ConvertTo-Json try { $release = Invoke-RestMethod -Method Get -Headers $headers -Uri "$baseUrl/releases/tags/$tag" } catch { $release = Invoke-RestMethod -Method Post -Headers $headers -ContentType "application/json" -Body $releaseBody -Uri "$baseUrl/releases" } foreach ($file in @("artifacts/OCSentinelClient-win-x64.zip", "artifacts/OCSentinelClient-win-x64.zip.sha256", "artifacts/version.json")) { $assetName = [System.IO.Path]::GetFileName($file) Invoke-RestMethod -Method Post -Headers $headers -InFile $file -ContentType "application/octet-stream" -Uri "$baseUrl/releases/$($release.id)/assets?name=$assetName" | Out-Null }