289 lines
7 KiB
Markdown
289 lines
7 KiB
Markdown
|
|
# 🔄 Forgejo Workflows
|
||
|
|
|
||
|
|
[](https://forgejo.org/)
|
||
|
|
[](.forgejo/workflows/release.yml)
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
Forgejo Actions orchestrates the entire pipeline from code commit to verified artifact. This document details the workflow in [`.forgejo/workflows/release.yml`](../../.forgejo/workflows/release.yml).
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## Workflow Structure
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
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
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
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
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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
|
||
|
|
|
||
|
|
```yaml
|
||
|
|
- name: Checkout
|
||
|
|
uses: actions/checkout@v3
|
||
|
|
```
|
||
|
|
|
||
|
|
**Purpose:** Clones the repository to the container.
|
||
|
|
|
||
|
|
### 3. Cross-Compile (MinGW)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
x86_64-w64-mingw32-gcc src/main.c -o dist/app.exe
|
||
|
|
```
|
||
|
|
|
||
|
|
**Purpose:** Compiles Windows executable from Linux.
|
||
|
|
|
||
|
|
### 4. Package (NSIS)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
makensis -DVERSION=${{ gitea.ref_name }} installer.nsi
|
||
|
|
```
|
||
|
|
|
||
|
|
**Purpose:** Creates Windows installer from compiled executable.
|
||
|
|
|
||
|
|
### 5. Code Sign
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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
|
||
|
|
|
||
|
|
```mermaid
|
||
|
|
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
|
||
|
|
|
||
|
|
```bash
|
||
|
|
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](../01-overview/architecture.md) |
|
||
|
|
| Troubleshoot | [Troubleshooting](../07-advanced/troubleshooting.md) |
|
||
|
|
| Manage evaluations | [Evaluation Management](../07-advanced/evaluation.md) |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
[← Documentation Index](../index.md) | [→ Advanced Topics](../07-advanced/) | [← Ansible Pipeline](../05-ansible/pipeline.md)
|