diff --git a/.forgejo/workflows/build-image.yml b/.forgejo/workflows/build-image.yml new file mode 100644 index 0000000..df3ad8c --- /dev/null +++ b/.forgejo/workflows/build-image.yml @@ -0,0 +1,193 @@ +name: "Build & Upload NixOS Proxmox Image" + +on: + push: + tags: + - "v*" # triggers on v1.0.0, v1.2.3, etc. + workflow_dispatch: + +jobs: + build: + name: Build NixOS Base Image + # Ensure 'nixos-latest' runner has Docker, SSH client, and basic Nix tools installed. + # It seems it already does. + runs-on: nixos-latest + env: + NIXOS_BUILER_HOST: nixos-builder.lab + NIXOS_BUILER_USER: runner + PROXMOX_HOST: 192.168.1.205 + PROXMOX_USER: plasmagoat + + # VM Template IDs for your Ansible playbook + # These are now passed to the playbook via --extra-vars, not directly as env vars for qm. + # They are defined in group_vars/all.yml, but can be overridden from here if needed. + # TEMPLATE_VMID: 9001 # Removed from direct env for explicit passing to Ansible + # LATEST_TEMPLATE_VMID: 9000 # Removed from direct env for explicit passing to Ansible + outputs: + image-name: ${{ steps.build_image.outputs.image_name_from_build }} + flake-metadata: ${{ steps.meta.outputs.metadata }} + image-url: ${{ steps.image-artifact.outputs.artifact-url }} + steps: + # Use nix-env for setup (as you prefer and it works well for ephemeral environments) + - name: Install dependencies via nix-env + run: | + nix-env -iA nixpkgs.nodejs + nix-env -iA nixpkgs.ansible + nix-env -iA nixpkgs.jq + nix-env -iA nixpkgs.gnused + nix-env -iA nixpkgs.coreutils + nix-env -iA nixpkgs.openssh + nix-env -iA cachix -f https://cachix.org/api/v1/install + cachix use plasmagoat + cachix authtoken ${{ secrets.CACHIX_AUTH_TOKEN }} + + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Enable experimental features + run: | + mkdir -p ~/.config/nix + echo "experimental-features = nix-command flakes" >> ~/.config/nix/nix.conf + + - name: Prepare SSH keys and known_hosts for builder and Proxmox + run: | + mkdir -p ~/.ssh + # Ensure this key corresponds to PROXMOX_USER + echo "${{ secrets.RUNNER_SSH_KEY }}" > ~/.ssh/id_rsa + chmod 600 ~/.ssh/id_rsa + # Add builder and Proxmox host keys to known_hosts + ssh-keyscan -H "$NIXOS_BUILER_HOST" >> ~/.ssh/known_hosts + ssh-keyscan -H "$PROXMOX_HOST" >> ~/.ssh/known_hosts + chmod 600 ~/.ssh/known_hosts + + - name: Test SSH connection to NixOS Builder + run: | + echo "Testing SSH connection to $NIXOS_BUILER_HOST..." + ssh -o StrictHostKeyChecking=yes "$NIXOS_BUILER_USER"@"$NIXOS_BUILER_HOST" "echo 'SSH success. Hostname:' && hostname" + + - name: Test SSH connection to Proxmox Host + run: | + echo "Testing SSH connection to $PROXMOX_HOST..." + ssh -o StrictHostKeyChecking=yes "$PROXMOX_USER"@"$PROXMOX_HOST" "echo 'SSH success. Hostname:' && hostname" + + - name: Build NixOS image + id: build_image + run: | + nix build .#base \ + --builders "ssh://$NIXOS_BUILER_USER@$NIXOS_BUILER_HOST x86_64-linux ~/.ssh/id_rsa 1 1 kvm" \ + --max-jobs 0 \ + --print-out-paths \ + | cachix push plasmagoat + + # Capture the actual image path from the result symlink for Ansible + IMAGE_PATH=$(find result/ -name "*.vma.zst" | head -n 1) + IMAGE_NAME=$(basename "$IMAGE_PATH") + if [ -z "$IMAGE_PATH" ]; then + echo "Error: No .vma.zst image found after build." + exit 1 + fi + echo "image_path_from_build=${IMAGE_PATH}" >> "$GITHUB_OUTPUT" + echo "image_name_from_build=${IMAGE_NAME}" >> "$GITHUB_OUTPUT" + + - name: Run Proxmox Image Deployment + run: | + chmod +x ./scripts/run_ansible_ci.sh + # Execute the script, passing necessary environment variables + bash scripts/run_ansible_ci.sh + env: + # These are passed directly to the `run_ansible_ci.sh` script, + # which then uses them to construct Ansible's --extra-vars. + # Match these variable names with what `run_ansible_ci.sh` expects. + # Note: The `image_path_from_build` comes from the previous step's output. + PROXMOX_LOCAL_IMAGE_PATH_FROM_BUILD: ${{ steps.build_image.outputs.image_path_from_build }} + + # Provide VMIDs and names, overriding group_vars if desired. + # These will be passed as `--extra-vars` to Ansible. + ANSIBLE_EXTRA_VARS: >- + backup_template_vmid={{ env.TEMPLATE_VMID | default('9001') }} + latest_template_vmid={{ env.LATEST_TEMPLATE_VMID | default('9000') }} + proxmox_host={{ env.PROXMOX_HOST }} + proxmox_user={{ env.PROXMOX_USER }} + remote_image_path_ci={{ steps.build_image.outputs.image_path_from_build }} + + - name: Extract flake metadata + id: meta + run: | + nix flake metadata --json > metadata.json + META=$(jq -r ' + .locks.nodes + | to_entries[] + | select(.key != "root") + | "* \(.key): \(.value.locked.url // ("github:\(.value.locked.owner)/\(.value.locked.repo)")) @ \(.value.locked.rev)" + ' <<< "$(nix flake metadata --json)") + + echo "metadata<> "$GITHUB_OUTPUT" + echo "$META" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + + - name: Upload Release Artifact + id: release-artifact + uses: forgejo/upload-artifact@v4 + if: ${{ steps.build_image.outputs.image_path_from_build }} + with: + name: release-artifact + path: metadata.json + + - name: Upload Image Artifact + id: image-artifact + uses: forgejo/upload-artifact@v4 + if: ${{ steps.build_image.outputs.image_path_from_build }} + with: + name: image-artifact + path: ${{ steps.build_image.outputs.image_path_from_build }} + + release: + name: Release Image + needs: build + runs-on: ubuntu-latest + if: success() + steps: + - name: Download Release Artifact + id: release-artifact + uses: forgejo/download-artifact@v4 + with: + name: release-artifact + + - name: Set version + id: version + run: | + if [[ "${{ github.ref_type }}" == "tag" ]]; then + TAG_NAME="${{ github.ref_name }}" + else + TAG_NAME="dev-$(date +%Y%m%d)-${GITHUB_SHA::7}" + fi + echo "Ref Type: ${{ github.ref_type }}" + echo "Ref Name: ${{ github.ref_name }}" + echo "Version: $TAG_NAME" + echo "tag_name=$TAG_NAME" >> "$GITHUB_OUTPUT" + + - name: Create Forgejo Release + uses: https://code.forgejo.org/sheik/forgejo-release@v2.6.0 + with: + title: "NixOS Base Image ${{ steps.version.outputs.tag_name }}" + prerelease: ${{ github.ref_type != 'tag' }} + tag: ${{ steps.version.outputs.tag_name }} + direction: upload + release-notes: | + ✅ **Base NixOS image uploaded** + + **🧱 Image File:** + `/var/lib/vz/dump/${{ needs.build.outputs.image-name }}` + + **🔗 Build Results:** + [View Build Logs](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}) + [Download Image](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}/artifacts/image-artifact) + [Download Image (action generated url)](${{ needs.build.outputs.image-url }}) + + **🔐 Flake Revision:** + `${{ github.sha }}` + + **📦 Flake Inputs:** + ${{ needs.build.outputs.flake-metadata }} + + release-dir: "${{ steps.release-artifact.outputs.download-path }}"