diff --git a/gitea/actions/local-ci-build/action.yml b/gitea/actions/local-ci-build/action.yml index 58e2bcc..6f5f524 100644 --- a/gitea/actions/local-ci-build/action.yml +++ b/gitea/actions/local-ci-build/action.yml @@ -139,6 +139,15 @@ inputs: required: false default: 'false' + skip-artifact: + description: > + Set to "true" to skip artifact packaging and collection entirely. + Use for jobs that intentionally produce no output (lint, static analysis, + test-only). When absent (default), the build MUST produce artifact-source + or the job fails. + required: false + default: 'false' + outputs: artifact-path: description: > @@ -174,6 +183,7 @@ runs: INPUT_REPO_URL: ${{ inputs.repo-url }} INPUT_EXTRA_GUEST_ENV_JSON: ${{ inputs.extra-guest-env-json }} INPUT_USE_SHARED_CACHE: ${{ inputs.use-shared-cache }} + INPUT_SKIP_ARTIFACT: ${{ inputs.skip-artifact }} run: | #Requires -Version 5.1 Set-StrictMode -Version Latest @@ -254,9 +264,10 @@ runs: Configuration = $env:INPUT_CONFIGURATION } - if ($env:INPUT_SUBMODULES -eq 'true') { $params['Submodules'] = $true } + if ($env:INPUT_SUBMODULES -eq 'true') { $params['Submodules'] = $true } if ($env:INPUT_USE_GIT_CLONE -eq 'true') { $params['UseGitClone'] = $true } if ($env:INPUT_USE_SHARED_CACHE -eq 'true') { $params['UseSharedCache'] = $true } + if ($env:INPUT_SKIP_ARTIFACT -eq 'true') { $params['SkipArtifact'] = $true } if ($resolvedTemplatePath) { $params['TemplatePath'] = $resolvedTemplatePath } if ($resolvedSnapshotName) { $params['SnapshotName'] = $resolvedSnapshotName } if ($extraGuestEnv.Count -gt 0) { $params['ExtraGuestEnv'] = $extraGuestEnv } @@ -270,7 +281,7 @@ runs: # ── Upload build artifacts on success ───────────────────────────────────── - name: Upload artifacts - if: success() + if: success() && inputs.skip-artifact != 'true' uses: actions/upload-artifact@v4 with: name: ${{ steps.invoke-ci.outputs.artifact-name }} diff --git a/scripts/Invoke-CIJob.ps1 b/scripts/Invoke-CIJob.ps1 index 6cd4f63..a2c1b07 100644 --- a/scripts/Invoke-CIJob.ps1 +++ b/scripts/Invoke-CIJob.ps1 @@ -105,6 +105,11 @@ param( # Requires Set-TemplateSharedFolders.ps1 to have been run on the template. [switch] $UseSharedCache, + # Skip artifact packaging (Invoke-RemoteBuild) and collection (Phase 6). + # Use for jobs that intentionally produce no output (lint, test-only, etc.). + # When absent, the build must produce GuestArtifactSource or the job fails. + [switch] $SkipArtifact, + # Credential Manager target for Gitea PAT used by -UseGitClone (private repos). # Store with: New-StoredCredential -Target 'GiteaPAT' -UserName '' -Password '' -Persist LocalMachine # Ignored when -UseGitClone is not set. @@ -494,12 +499,17 @@ try { if ($GuestArtifactSource -ne '') { $remoteBuildParams['GuestArtifactSource'] = $GuestArtifactSource } if ($ExtraGuestEnv.Count -gt 0) { $remoteBuildParams['ExtraGuestEnv'] = $ExtraGuestEnv } if ($UseSharedCache) { $remoteBuildParams['UseSharedCache'] = $true } + if ($SkipArtifact) { $remoteBuildParams['SkipArtifact'] = $true } & "$scriptDir\Invoke-RemoteBuild.ps1" @remoteBuildParams Write-JobEvent -Phase 'phase5.build' -Status 'success' $phaseTimings.Add([PSCustomObject]@{ Phase = 'Phase 5 - Remote build'; Sec = [int]((Get-Date) - $phaseStart).TotalSeconds }) $phaseStart = Get-Date # ── Phase 6: Collect artifacts ──────────────────────────────────────── + if ($SkipArtifact) { + Write-Host "`n[Phase 6/6] Artifact collection skipped (-SkipArtifact)." + Write-JobEvent -Phase 'phase6.artifacts' -Status 'skipped' + } else { Write-Host "`n[Phase 6/6] Collecting artifacts..." Write-JobEvent -Phase 'phase6.artifacts' -Status 'start' if ($GuestOS -eq 'Linux') { @@ -520,7 +530,8 @@ try { -HostArtifactDir $jobArtifactDir ` -IncludeLogs } - Write-JobEvent -Phase 'phase6.artifacts' -Status 'success' -Data @{ dir = $jobArtifactDir } + Write-JobEvent -Phase 'phase6.artifacts' -Status 'success' -Data @{ dir = $jobArtifactDir } + } $elapsed = (Get-Date) - $startTime Write-JobEvent -Phase 'job' -Status 'success' -Data @{ elapsedSec = [int]$elapsed.TotalSeconds } $phaseTimings.Add([PSCustomObject]@{ Phase = 'Phase 6 - Artifacts'; Sec = [int]((Get-Date) - $phaseStart).TotalSeconds }) diff --git a/scripts/Invoke-RemoteBuild.ps1 b/scripts/Invoke-RemoteBuild.ps1 index 80ee488..6c180a4 100644 --- a/scripts/Invoke-RemoteBuild.ps1 +++ b/scripts/Invoke-RemoteBuild.ps1 @@ -126,6 +126,10 @@ param( # and VMware Tools HGFS driver present in the guest. [switch] $UseSharedCache, + # Skip artifact packaging entirely. Use for jobs that produce no output. + # When absent, missing GuestArtifactSource after a successful build is an error. + [switch] $SkipArtifact, + # Guest OS type — Linux uses SSH instead of WinRM. [ValidateSet('Windows', 'Linux')] [string] $GuestOS = 'Windows', @@ -427,7 +431,7 @@ try { # ── Custom build command (e.g. python, msbuild, cmake…) ────────── Write-Host "[Invoke-RemoteBuild] Running build command: $BuildCommand" $buildExit = Invoke-Command -Session $session -ScriptBlock { - param($workDir, $cmd, $artifactZip, $artifactSrc, $useCache, $extraEnv) + param($workDir, $cmd, $artifactZip, $artifactSrc, $useCache, $extraEnv, $skipArt) # Unbuffered Python output — lines appear in real-time instead of being held in buffer $env:PYTHONUNBUFFERED = '1' if ($useCache) { @@ -442,14 +446,14 @@ try { & cmd /c "$cmd 2>&1" | ForEach-Object { Write-Host $_ } $exit = $LASTEXITCODE - if ($exit -eq 0) { + if ($exit -eq 0 -and -not $skipArt) { $archiveDir = Split-Path $artifactZip -Parent if (-not (Test-Path $archiveDir)) { New-Item -ItemType Directory -Path $archiveDir -Force | Out-Null } $srcPath = Join-Path $workDir $artifactSrc if (-not (Test-Path $srcPath)) { - throw "Artifact source directory not found: $srcPath. Build succeeded (exit 0) but produced no output. Check GuestArtifactSource." + throw "Artifact source directory not found: $srcPath. Build succeeded (exit 0) but produced no output. Check GuestArtifactSource or set skip-artifact: 'true' in the workflow." } else { $7zip = 'C:\Program Files\7-Zip\7z.exe' @@ -465,7 +469,7 @@ try { } return $exit - } -ArgumentList $GuestWorkDir, $BuildCommand, $GuestArtifactZip, $GuestArtifactSource, $UseSharedCache.IsPresent, $ExtraGuestEnv + } -ArgumentList $GuestWorkDir, $BuildCommand, $GuestArtifactZip, $GuestArtifactSource, $UseSharedCache.IsPresent, $ExtraGuestEnv, $SkipArtifact.IsPresent if ($buildExit -ne 0) { throw "Build command failed (exit $buildExit)" @@ -528,7 +532,11 @@ try { } } - Write-Host "[Invoke-RemoteBuild] Build succeeded. Artifact at $GuestArtifactZip" + if ($SkipArtifact) { + Write-Host '[Invoke-RemoteBuild] Build succeeded. Artifact packaging skipped (-SkipArtifact).' + } else { + Write-Host "[Invoke-RemoteBuild] Build succeeded. Artifact at $GuestArtifactZip" + } } finally { Remove-PSSession $session -ErrorAction SilentlyContinue