Files
local-ci-cd-system/gitea/workflow-example.yml
T
Simone 7d12dedddd Sprint 13-14: §6.2 composite action + §6.4 build matrix + §6.5 secret injection
§6.2 - New composite action gitea/actions/local-ci-build/action.yml
  Wraps Invoke-CIJob.ps1 for reuse across repos. Inputs: build-command,
  artifact-source, submodules, guest-os, use-git-clone, configuration,
  template-path, snapshot-name, artifact-name, artifact-retention-days.
  Anti-injection: all params via INPUT_* env vars, never interpolated in shell.

§6.4 - Build matrix windows+linux in build-nsis.yml
  gitea/workflows/build-nsis.yml rewritten with strategy.matrix target:
  [windows, linux], fail-fast: false, routes to {target}-build runner.
  Added action inputs: job-id-suffix (matrix disambig for artifact dirs),
  repo-url (SSH URL override for gitea-ci alias).

§6.5 - ExtraGuestEnv secret injection chain
  New param -ExtraGuestEnv [hashtable] in Invoke-CIJob.ps1 and
  Invoke-RemoteBuild.ps1. Windows: SetEnvironmentVariable in WinRM session
  ScriptBlock before build command. Linux: export KEY='val'; prefix before
  cd && buildcmd (POSIX single-quote escaping). Composite action input
  extra-guest-env-json (JSON object -> ConvertFrom-Json -> hashtable),
  never logged.

PSScriptAnalyzer fixes: _Common.psm1, Invoke-RetentionPolicy.ps1,
  Watch-RunnerHealth.ps1 (empty catch, ShouldProcess suppression, etc.)

Docs/test: TEST-PLAN-v1.3-to-HEAD.md updated §3.3/§6.1/§5.4 status.
  TODO.md: §6 fully closed (6.1-6.2 done, 6.3 deferred, 6.4-6.5 done, 6.6 done).
2026-05-11 22:35:36 +02:00

218 lines
7.5 KiB
YAML

# Gitea Actions workflow: .NET build with ephemeral VMware VM
# Copy this file to: .gitea/workflows/build.yml in your repository.
#
# This workflow triggers on push to main/develop and on pull requests.
# It routes the job to the act_runner with label "windows-build",
# which creates an isolated VM per build.
name: Build (.NET / MSBuild)
on:
push:
branches:
- main
- develop
- 'release/**'
pull_request:
branches:
- main
- develop
jobs:
build:
# Must match the runner label defined in runner/config.yaml
runs-on: windows-build
# Job-level timeout (should be less than the runner's timeout setting)
timeout-minutes: 90
env:
# Override these per-repository or in Gitea's repository secrets
# GITEA_CI_TEMPLATE_PATH is injected by runner/config.yaml global envs
# GITEA_CI_CLONE_BASE_DIR is injected by runner/config.yaml global envs
# Gitea Credential Manager target (set in runner/config.yaml)
# The VM IP is auto-detected via vmrun getGuestIPAddress — no BUILD_VM_IP needed.
GUEST_CRED_TARGET: "BuildVMGuest"
steps:
# Step 1: Check out the repository on the RUNNER HOST
# (This gives the runner access to the scripts/ directory)
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 1
# Step 2: Invoke the orchestrator script
# This script handles the entire VM lifecycle:
# clone → start → wait ready → build → collect artifacts → destroy
- name: Build in ephemeral VM
shell: powershell
run: |
$ErrorActionPreference = 'Stop'
# CI scripts are at a fixed location on the runner host.
# Do NOT use $env:GITHUB_WORKSPACE — the CI system is in a separate repo.
$ciScriptsDir = 'N:\Code\Workspace\Local-CI-CD-System\scripts'
& "$ciScriptsDir\Invoke-CIJob.ps1" `
-JobId "${{ github.run_id }}-${{ github.run_attempt }}" `
-RepoUrl "ssh://gitea-ci/${{ github.repository }}.git" `
-Branch "${{ github.ref_name }}" `
-Commit "${{ github.sha }}" `
-Submodules `
-BuildCommand 'python build_plugin.py --final --dist-dir dist' `
-GuestArtifactSource 'dist' `
-GuestCredentialTarget "$env:GUEST_CRED_TARGET"
if ($LASTEXITCODE -ne 0) {
exit $LASTEXITCODE
}
# Step 3: Upload artifacts to Gitea
# Artifacts were collected to F:\CI\Artifacts\{JobId}\ by Invoke-CIJob.ps1
- name: Upload build artifacts
if: success()
uses: actions/upload-artifact@v4
with:
name: build-${{ github.sha }}
path: F:\CI\Artifacts\${{ github.run_id }}-${{ github.run_attempt }}\
retention-days: 14
if-no-files-found: error
# Step 4: Upload artifacts even on failure (for diagnostics)
- name: Upload diagnostic logs on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: build-logs-${{ github.sha }}
path: F:\CI\Artifacts\${{ github.run_id }}-${{ github.run_attempt }}\*.log
retention-days: 3
if-no-files-found: ignore
---
# PARALLEL BUILD VARIANT (using matrix strategy)
# Uncomment and adapt if you need to build multiple configurations in parallel.
#
# jobs:
# build:
# runs-on: windows-build
# strategy:
# matrix:
# include:
# - config: Release
# vm_ip: "192.168.11.101"
# - config: Debug
# vm_ip: "192.168.11.102"
# fail-fast: false
#
# steps:
# - uses: actions/checkout@v4
# - name: Build (${{ matrix.config }})
# shell: pwsh
# run: |
# & scripts\Invoke-CIJob.ps1 `
# -JobId "${{ github.run_id }}-${{ matrix.config }}" `
# -RepoUrl "${{ github.server_url }}/${{ github.repository }}.git" `
# -Branch "${{ github.ref_name }}" `
# -Configuration "${{ matrix.config }}" `
# -VMIPAddress "${{ matrix.vm_ip }}"
---
# CROSS-PLATFORM MATRIX BUILD (Windows + Linux VMs)
# Runs the same build on both Windows and Linux ephemeral VMs in parallel.
# Requires:
# - runner/config.yaml labels include "windows-build:host" and "linux-build:host"
# - Linux template provisioned: F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx
# - SSH key at F:\CI\keys\ci_linux (ed25519, no passphrase), user ci_build
#
# jobs:
# build:
# strategy:
# matrix:
# target: [windows, linux]
# fail-fast: false
#
# runs-on: ${{ matrix.target }}-build
#
# steps:
# - uses: actions/checkout@v4
#
# - name: Build on ${{ matrix.target }}
# shell: pwsh
# run: |
# $ErrorActionPreference = 'Stop'
# $ciScriptsDir = Join-Path $env:GITHUB_WORKSPACE 'scripts'
#
# $templatePath = if ('${{ matrix.target }}' -eq 'linux') {
# $env:GITEA_CI_LINUX_TEMPLATE_PATH # F:\CI\Templates\LinuxBuild2404\LinuxBuild2404.vmx
# } else {
# $env:GITEA_CI_TEMPLATE_PATH # F:\CI\Templates\WinBuild2025\WinBuild2025.vmx
# }
#
# & "$ciScriptsDir\Invoke-CIJob.ps1" `
# -JobId "${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.target }}" `
# -RepoUrl "${{ github.server_url }}/${{ github.repository }}.git" `
# -Branch "${{ github.ref_name }}" `
# -Commit "${{ github.sha }}" `
# -TemplatePath $templatePath `
# -BuildCommand 'make all'
#
# - name: Upload artifacts (${{ matrix.target }})
# if: success()
# uses: actions/upload-artifact@v4
# with:
# name: build-${{ matrix.target }}-${{ github.sha }}
# path: F:\CI\Artifacts\${{ github.run_id }}-${{ github.run_attempt }}-${{ matrix.target }}\
# retention-days: 14
# if-no-files-found: error
---
# COMPOSITE ACTION VARIANT (recommended for new repositories)
# Uses the reusable composite action stored in the CI system repository.
# This variant replaces the verbose inline shell block with a single `uses:` step.
# The composite action handles: Invoke-CIJob.ps1 call + artifact upload + log upload.
#
# Reference: gitea/actions/local-ci-build/action.yml in this repository.
# Deployed path in Gitea: Simone/local-ci-system / .gitea/actions/local-ci-build/action.yml
#
# Minimum example (Windows build, Python project with submodules):
#
# name: Build (Composite)
#
# on:
# push:
# tags:
# - 'v*'
# workflow_dispatch:
#
# jobs:
# build:
# runs-on: windows-build
# steps:
# - uses: actions/checkout@v4
# - uses: Simone/local-ci-system/.gitea/actions/local-ci-build@main
# with:
# build-command: 'python build_plugin.py --final --dist-dir dist'
# artifact-source: 'dist'
# submodules: 'true'
#
# Cross-platform matrix variant using the composite action:
#
# jobs:
# build:
# strategy:
# matrix:
# target: [windows, linux]
# fail-fast: false
# runs-on: ${{ matrix.target }}-build
# steps:
# - uses: actions/checkout@v4
# - uses: Simone/local-ci-system/.gitea/actions/local-ci-build@main
# with:
# build-command: 'python build_plugin.py --final --dist-dir dist'
# artifact-source: 'dist'
# submodules: 'true'
# guest-os: 'Auto'
# artifact-name: 'build-${{ matrix.target }}-${{ github.sha }}'