chore: initial commit local CI/CD system (e2e verified, production-ready)
Sistema CI locale basato su VMware Workstation + Gitea Actions + act_runner. Testato e2e con nsis-plugin-nsinnounp (MSBuild + Python, 4 configurazioni parallele). - scripts/: Invoke-CIJob, Invoke-RemoteBuild, New/Remove-BuildVM, Wait-VMReady, Get-BuildArtifacts - runner/: act_runner config (windows-build label, capacity 4) - gitea/workflows/: build-nsis.yml (template per progetti MSBuild/Python) - template/: script di provisioning template VM (VS BuildTools 2026, .NET SDK 10, Python 3.13) - docs/: ARCHITECTURE, CI-FLOW, OPTIMIZATION, BEST-PRACTICES, Setup-GiteaSSH Verificato: e2e-009 SUCCESS in 02:09, cleanup automatico VM confermato.
This commit is contained in:
@@ -0,0 +1,124 @@
|
||||
# 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
|
||||
|
||||
# IP address for this build VM.
|
||||
# For parallel builds, each concurrent job needs a unique IP.
|
||||
# Assign via Gitea matrix or a simple offset scheme.
|
||||
# Example: use a fixed IP per runner slot, mapped by capacity index.
|
||||
# For single concurrent builds: use one fixed IP.
|
||||
BUILD_VM_IP: "192.168.11.101"
|
||||
|
||||
# Gitea Credential Manager target (set in runner/config.yaml)
|
||||
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: pwsh
|
||||
run: |
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# Resolve the scripts directory relative to the checked-out repo.
|
||||
# If your CI scripts are in a separate repo, adjust the path.
|
||||
$ciScriptsDir = Join-Path $env:GITHUB_WORKSPACE 'scripts'
|
||||
|
||||
& "$ciScriptsDir\Invoke-CIJob.ps1" `
|
||||
-JobId "${{ github.run_id }}-${{ github.run_attempt }}" `
|
||||
-RepoUrl "${{ github.server_url }}/${{ github.repository }}.git" `
|
||||
-Branch "${{ github.ref_name }}" `
|
||||
-Commit "${{ github.sha }}" `
|
||||
-Configuration "Release" `
|
||||
-VMIPAddress "$env:BUILD_VM_IP" `
|
||||
-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 }}"
|
||||
@@ -0,0 +1,46 @@
|
||||
# Build (Local CI) — pipeline per nsis-plugin-nsinnounp
|
||||
#
|
||||
# Eseguito dal runner locale windows-build su WS1-W11.
|
||||
# L'orchestratore (Invoke-CIJob.ps1) gira sull'host e:
|
||||
# 1. Clona il repo sull'host (con submoduli)
|
||||
# 2. Crea una VM efimera da snapshot BaseClean
|
||||
# 3. Copia il sorgente nella VM via WinRM (zip transfer)
|
||||
# 4. Esegue python build_plugin.py nella VM
|
||||
# 5. Raccoglie artifacts.zip sull'host
|
||||
# 6. Distrugge la VM
|
||||
#
|
||||
# Trigger: push su tag v*, oppure run manuale
|
||||
|
||||
name: Build (Local CI)
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: windows-build
|
||||
|
||||
steps:
|
||||
- name: Run CI Job
|
||||
shell: pwsh
|
||||
run: |
|
||||
& 'N:\Code\Workspace\Local-CI-CD-System\scripts\Invoke-CIJob.ps1' `
|
||||
-JobId '${{ github.run_id }}' `
|
||||
-RepoUrl 'ssh://gitea-ci/Simone/nsis-plugin-nsinnounp.git' `
|
||||
-Branch '${{ github.ref_name }}' `
|
||||
-Commit '${{ github.sha }}' `
|
||||
-TemplatePath $env:GITEA_CI_TEMPLATE_PATH `
|
||||
-Submodules `
|
||||
-BuildCommand 'python build_plugin.py --final --dist-dir dist' `
|
||||
-GuestArtifactSource 'dist'
|
||||
if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE }
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: nsis-plugin-nsinnounp-${{ github.ref_name }}
|
||||
path: F:\CI\Artifacts\${{ github.run_id }}\artifacts.zip
|
||||
if-no-files-found: error
|
||||
Reference in New Issue
Block a user