windows-iac-vm-tooling/docs/06-ci-cd/forgejo-workflows.md
root e4f03427b7
Some checks are pending
Build and Release / build-sign-package (push) Waiting to run
feat: Add professional hierarchical documentation
- Created comprehensive README.md with Mermaid diagrams, badges, and TOC
- Added docs/ directory with 7 sections and 14 markdown files
- Included architecture diagrams, flowcharts, and sequence diagrams
- All documentation is fully interlinked with cross-references
- Added ISO storage location on Proxmox development server
- Included troubleshooting guide and evaluation management docs
- All config files (Packer, Terraform, Ansible, Forgejo) documented
- Added icons and visual elements throughout documentation
2026-02-06 14:47:15 +00:00

7 KiB

🔄 Forgejo Workflows

Forgejo CI/CD

Overview

Forgejo Actions orchestrates the entire pipeline from code commit to verified artifact. This document details the workflow in .forgejo/workflows/release.yml.


Workflow Structure

flowchart TB
    subgraph Workflow["Forgejo Workflow"]
        direction LR
        Trigger[on: push] --> Job[build-sign-package]
        Job --> Steps[6 Steps]
    end
    
    subgraph Steps["Job Steps"]
        direction TB
        Install[Install Tools] --> Checkout[Checkout] --> Compile[Cross-Compile] --> Package[Package] --> Sign[Sign] --> Provision[Provision VM] --> Verify[Verify] --> Cleanup[Cleanup]
    end
    
    style Workflow fill:#e3f2fd
    style Steps fill:#e8f5e9

Full Workflow Configuration

name: Build and Release
on: [push]

jobs:
  build-sign-package:
    runs-on: ubuntu-latest
    container: archlinux:latest
    steps:
      - name: Install Tools
        run: |
          pacman -Syu --noconfirm \
            mingw-w64-gcc \
            nsis \
            osslsigncode \
            opentofu \
            ansible \
            python-pywinrm \
            packer

      - name: Checkout
        uses: actions/checkout@v3

      - name: Cross-Compile (MinGW)
        run: |
          x86_64-w64-mingw32-gcc src/main.c -o dist/app.exe

      - name: Package (NSIS)
        run: |
          makensis -DVERSION=${{ gitea.ref_name }} installer.nsi

      - name: Code Sign (Linux Native)
        env:
          PFX_PASS: ${{ secrets.PFX_PASS }}
        run: |
          osslsigncode sign \
            -pkcs12 cert.pfx \
            -pass "$PFX_PASS" \
            -t http://timestamp.digicert.com \
            -in dist/installer.exe \
            -out dist/installer_signed.exe

      - name: Provision Windows VM (OpenTofu)
        env:
          PM_API_TOKEN_ID: ${{ secrets.PM_TOKEN_ID }}
          PM_API_TOKEN_SECRET: ${{ secrets.PM_TOKEN_SECRET }}
          TF_VAR_build_id: ${{ gitea.run_number }}
        run: |
          cd terraform
          tofu init
          tofu apply -auto-approve
          echo "VM_IP=$(tofu output -raw vm_ip)" >> $GITHUB_ENV

      - name: Verify on Windows (Ansible)
        env:
          ANSIBLE_USER: Administrator
          ANSIBLE_PASSWORD: ${{ secrets.WIN_ADMIN_PASS }}
        run: |
          echo "[windows_vm]" > inventory.ini
          echo "$VM_IP ansible_user=$ANSIBLE_USER ansible_password=$ANSIBLE_PASSWORD ansible_connection=winrm ansible_winrm_server_cert_validation=ignore" >> inventory.ini
          
          ansible-playbook -i inventory.ini ansible/pipeline.yml

      - name: Cleanup
        if: always()
        run: |
          cd terraform
          tofu destroy -auto-approve

Step-by-Step Breakdown

1. Install Tools

pacman -Syu --noconfirm \
  mingw-w64-gcc \    # MinGW cross-compiler
  nsis \             # NSIS installer builder
  osslsigncode \     # Code signing tool
  opentofu \         # Infrastructure as code
  ansible \          # Automation
  python-pywinrm \  # Ansible WinRM support
  packer \           # Image builder

2. Checkout

- name: Checkout
  uses: actions/checkout@v3

Purpose: Clones the repository to the container.

3. Cross-Compile (MinGW)

x86_64-w64-mingw32-gcc src/main.c -o dist/app.exe

Purpose: Compiles Windows executable from Linux.

4. Package (NSIS)

makensis -DVERSION=${{ gitea.ref_name }} installer.nsi

Purpose: Creates Windows installer from compiled executable.

5. Code Sign

osslsigncode sign \
  -pkcs12 cert.pfx \
  -pass "$PFX_PASS" \
  -t http://timestamp.digicert.com \
  -in dist/installer.exe \
  -out dist/installer_signed.exe

Purpose: Authenticode sign the installer with timestamp.

6. Provision VM (OpenTofu)

cd terraform
tofu init
tofu apply -auto-approve
echo "VM_IP=$(tofu output -raw vm_ip)" >> $GITHUB_ENV

Purpose: Creates ephemeral Windows VM for testing.

7. Verify (Ansible)

echo "[windows_vm]" > inventory.ini
echo "$VM_IP ansible_user=$ANSIBLE_USER ..." >> inventory.ini
ansible-playbook -i inventory.ini ansible/pipeline.yml

Purpose: Tests installer on live Windows VM.

8. Cleanup

if: always()
tofu destroy -auto-approve

Purpose: Destroys VM regardless of test result.


Container Configuration

Setting Value Description
runs-on ubuntu-latest Runner OS
container archlinux:latest Build container

Why Arch Linux?

  • Latest packages available
  • Excellent AUR support
  • Small footprint
  • Easy package management

Environment Variables

Set by Workflow

Variable Source Purpose
VM_IP OpenTofu output Windows VM IP address
GITHUB_ENV Workflow Store VM_IP for subsequent steps

From Secrets

Secret Env Var Purpose
PFX_PASS PFX_PASS Certificate password
PM_TOKEN_ID PM_API_TOKEN_ID Proxmox authentication
PM_TOKEN_SECRET PM_API_TOKEN_SECRET Proxmox authentication
WIN_ADMIN_PASS ANSIBLE_PASSWORD WinRM connection

Pipeline Flow Diagram

flowchart TB
    subgraph Build["Build Stage"]
        direction LR
        Install[Install Tools] --> Checkout[Checkout] --> Compile[Cross-Compile] --> Package[Package] --> Sign[Sign]
    end
    
    subgraph Deploy["Deploy Stage"]
        Sign --> Provision[Provision VM] --> Verify[Ansible Verify]
    end
    
    subgraph Cleanup["Cleanup Stage"]
        Verify --> Destroy[Destroy VM]
    end
    
    style Build fill:#e3f2fd
    style Deploy fill:#e8f5e9
    style Cleanup fill:#fff3e0

Triggering the Pipeline

Trigger Description
on: push Runs on any push to any branch
on: [push, pull_request] Also run on PRs (optional)

Manual Trigger

git commit -m "Update installer"
git push

Troubleshooting

Issue Cause Solution
Container missing packages Pacman cache Clear cache or use specific versions
OpenTofu init fails Provider issues Run tofu init -upgrade
Ansible connection timeout WinRM not ready Check Autounattend.xml
Cleanup failed VM already destroyed Add if: failure() condition

Next Steps

Goal Next Document
View architecture Architecture Overview
Troubleshoot Troubleshooting
Manage evaluations Evaluation Management

← Documentation Index | → Advanced Topics | ← Ansible Pipeline