Skip to content

GitFlow | Nightly Builds #290

GitFlow | Nightly Builds

GitFlow | Nightly Builds #290

# This workflow creates nightly builds from the develop branch:
# - Checks for merged PRs since the last tag
# - Creates a pre-release version if changes are detected
# - Builds and packages the software
# - Creates GitHub release with artifacts
name: GitFlow | Nightly Builds
on:
# Automated nightly builds at midnight
schedule:
- cron: "0 0 * * *"
# Manual trigger for testing purposes
workflow_dispatch:
permissions:
contents: write
jobs:
build:
name: Create Nightly Build
runs-on: windows-latest
env:
# Define the branch as a variable
BRANCH: develop
steps:
# Step 1: Checkout the develop branch for nightly builds
- name: Checkout code
uses: actions/checkout@v6
with:
lfs: "true"
fetch-depth: 0
# Always checkout develop for nightly builds
ref: ${{ env.BRANCH }}
# Step 2: Verify if a new build is required by checking for merged PRs since last tag
- name: Check for merged PRs since last tag
id: check_prs
shell: powershell
run: |
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "Checking for new changes since last release" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
# Initialize BUILD_NEEDED with default value
$BUILD_NEEDED = $false
# Get the latest release tag to determine release type
$LATEST_TAG = git tag -l --sort=-version:refname | Select-Object -First 1
Write-Host "`n[INFO] Latest release tag: $LATEST_TAG" -ForegroundColor Green
# Determine release type based on previous tag
if ($LATEST_TAG -like "*-*") {
# Previous tag is a prerelease -> increment suffix (e.g., v2.9.1-0 -> v2.9.1-1)
$RELEASE_TYPE = "prerelease"
Write-Host "[INFO] Previous tag is a prerelease -> using 'prerelease' to increment suffix" -ForegroundColor Cyan
} else {
# Previous tag is stable -> create first prerelease (e.g., v2.9.0 -> v2.10.0-0)
$RELEASE_TYPE = "preminor"
Write-Host "[INFO] Previous tag is stable -> using 'preminor' to create first prerelease" -ForegroundColor Cyan
}
# Manual trigger always builds
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
Write-Host "`n[MANUAL] Manual trigger detected - forcing build" -ForegroundColor Magenta
Write-Host "[BUILD] Building new prerelease version (type: $RELEASE_TYPE)." -ForegroundColor Green
$BUILD_NEEDED = $true
}
else {
# Automated nightly: check for changes first
Write-Host "`n[AUTO] Scheduled nightly build - checking for changes..." -ForegroundColor Cyan
# Get the commit date of the latest tag (compatible with PowerShell 5.1)
$TAG_DATE_FORMATTED = git log -1 --format=%ci $LATEST_TAG
Write-Host "[INFO] Tag creation date: $TAG_DATE_FORMATTED" -ForegroundColor Green
# Get tag commit SHA
$TAG_COMMIT = git rev-list -n 1 $LATEST_TAG
Write-Host "[INFO] Tag commit SHA: $TAG_COMMIT" -ForegroundColor Green
# Get current branch and HEAD commit
$BRANCH = "${{ env.BRANCH }}"
$HEAD_COMMIT = git rev-parse HEAD
Write-Host "[INFO] Current branch: $BRANCH" -ForegroundColor Green
Write-Host "[INFO] Current HEAD: $HEAD_COMMIT" -ForegroundColor Green
# Check if tag commit is the same as HEAD
if ($TAG_COMMIT -eq $HEAD_COMMIT) {
Write-Host "`n[SKIP] Tag commit is identical to current HEAD. No new changes." -ForegroundColor Yellow
$BUILD_NEEDED = $false
}
else {
Write-Host "`n[INFO] Searching for merged PRs between $TAG_COMMIT and HEAD..." -ForegroundColor Cyan
# Get all merged PRs to the branch since the tag commit
$MERGED_PRS = git log --merges --grep="Merge pull request" --pretty=format:"%h %s" "$TAG_COMMIT..HEAD"
# Count merges
$MERGE_COUNT = ($MERGED_PRS | Measure-Object).Count
Write-Host "[INFO] Found $MERGE_COUNT merged PR(s)" -ForegroundColor Green
if ($MERGE_COUNT -eq 0) {
Write-Host "`n[SKIP] No PRs merged to $BRANCH since last tag. Skipping build." -ForegroundColor Yellow
$BUILD_NEEDED = $false
}
else {
Write-Host "`n[INFO] Merged PRs since last tag:" -ForegroundColor Cyan
$MERGED_PRS | ForEach-Object { Write-Host " - $_" -ForegroundColor White }
if ($MERGE_COUNT -eq 1 -and $MERGED_PRS -match "Merge pull request #\d+ from .*/release/") {
Write-Host "`n[SKIP] Only change since last tag is a release PR merge. Skipping build." -ForegroundColor Yellow
$BUILD_NEEDED = $false
}
else {
Write-Host "`n[BUILD] Building new prerelease version (type: $RELEASE_TYPE)." -ForegroundColor Green
$BUILD_NEEDED = $true
}
}
}
}
Write-Host "`n========================================" -ForegroundColor Cyan
Write-Host "Build needed: $BUILD_NEEDED" -ForegroundColor $(if ($BUILD_NEEDED -eq $true) { "Green" } else { "Yellow" })
Write-Host "Release type: $RELEASE_TYPE" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
echo "BUILD_NEEDED=$BUILD_NEEDED" >> $env:GITHUB_OUTPUT
echo "RELEASE_TYPE=$RELEASE_TYPE" >> $env:GITHUB_OUTPUT
# Step 3: Generate new semantic version number
- name: Auto Increment Semver Action
uses: MCKanpolat/auto-semver-action@5003b8d37f4b03d95f15303ea10242cbf7c13141 # 2
if: steps.check_prs.outputs.BUILD_NEEDED == 'true'
id: versioning
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
incrementPerCommit: false
releaseType: ${{ steps.check_prs.outputs.RELEASE_TYPE }}
# Step 4: Format version numbers for different purposes (SemVer, MSI version)
- name: Format Semver (and MSI version)
if: steps.check_prs.outputs.BUILD_NEEDED == 'true'
id: format_version
shell: powershell
run: |
# Get version from previous step
$NextSemver = "${{ steps.versioning.outputs.version }}"
# Create MSI-compatible version (x.y.z.build)
$commit_count = (git rev-list --count HEAD)
$commit_count_mod = $commit_count % 65535 # MSI has a version limit
$MsiBase = $NextSemver.Split("-")[0] # Remove prerelease segment
$MsiVersion = "$MsiBase.$commit_count_mod"
# Format the release name based on trigger type
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
$ReleaseName = "WAU $NextSemver [Pre-release Build]"
$ReleaseBodyIntro = "This is a **pre-release build** created from the latest changes in the develop branch."
} else {
$ReleaseName = "WAU $NextSemver [Nightly Build]"
$ReleaseBodyIntro = "This is an **automated nightly build** created from the latest changes in the develop branch."
}
# Output all version information
echo "MSI version: $MsiVersion"
echo "Semver created: $NextSemver"
echo "Release name: $ReleaseName"
echo "Release body intro: $ReleaseBodyIntro"
echo "MsiVersion=$MsiVersion" >> $env:GITHUB_OUTPUT
echo "NextSemVer=$NextSemver" >> $env:GITHUB_OUTPUT
echo "ReleaseName=$ReleaseName" >> $env:GITHUB_OUTPUT
echo "ReleaseBodyIntro=$ReleaseBodyIntro" >> $env:GITHUB_OUTPUT
# Step 5: Build the project and generate artifacts
- name: Build project
if: steps.check_prs.outputs.BUILD_NEEDED == 'true'
id: build_project
shell: powershell
run: |
# Download and install Microsoft Deployment Toolkit
echo "### Get MDT from Microsoft ###"
wget https://download.microsoft.com/download/3/3/9/339BE62D-B4B8-4956-B58D-73C4685FC492/MicrosoftDeploymentToolkit_x64.msi -UseBasicParsing -OutFile .\MicrosoftDeploymentToolkit_x64.msi
Start-Process .\MicrosoftDeploymentToolkit_x64.msi -ArgumentList "/quiet /norestart" -Wait
# Extract ServiceUI for elevated notifications
echo "### Copy ServiceUI.exe x64 to 'Sources\Winget-AutoUpdate' folder ###"
Copy-Item -Path "C:\Program Files\Microsoft Deployment Toolkit\Templates\Distribution\Tools\x64\ServiceUI.exe" -Destination ".\Sources\Winget-AutoUpdate\ServiceUI.exe" -Force
Get-Item .\Sources\Winget-AutoUpdate\*
# Install WiX tools for MSI creation
echo "### Install WiX ###"
dotnet new console
dotnet tool install --global wix --version 5.0.1
wix extension add WixToolset.UI.wixext/5.0.1 -g
wix extension add WixToolset.Util.wixext/5.0.1 -g
# Build MSI package with version information
echo "### Create WAU MSI ###"
cd .\Sources\Wix\
wix build -src build.wxs -ext WixToolset.Util.wixext -ext WixToolset.UI.wixext -out ..\..\WAU.msi -arch x64 -d Version=${{ steps.format_version.outputs.MsiVersion }} -d NextSemVer=${{ steps.format_version.outputs.NextSemVer }} -d Comment="${{ steps.format_version.outputs.ReleaseName }}" -d PreRelease=1
cd ..\..
Get-Item .\WAU.msi
# Calculate MSI file hash for verification
echo "### Get MSI file SHA ###"
$MsiSHA = (Get-FileHash .\WAU.msi).hash
echo " - WAU.msi SHA256: $MsiSHA"
echo "msi_sha=$MsiSHA" >> $env:GITHUB_OUTPUT
# Package ADMX policy templates
echo "### Zip ADMX ###"
$admxPath = ".\Sources\Policies\ADMX\WAU.admx"
try {
(Get-Content $admxPath -Raw -ErrorAction Stop) -match 'revision="([\d\.]+)"' | Out-Null
$ADMXversion = $matches[1]
$admxZip = "WAU_ADMX_$($ADMXversion).zip"
}
catch {
Write-Host "Error getting WAU ADMX version!"
$admxZip = "WAU_ADMX.zip"
}
Compress-Archive -Path .\Sources\Policies\ADMX -DestinationPath .\$admxZip -Force
Get-Item .\*.zip
echo "admx_zip_name=$admxZip" >> $env:GITHUB_OUTPUT
# Calculate ADMX package hash for verification
echo "### Get ADMX zip SHA ###"
$ADMXSHA = (Get-FileHash .\$admxZip).hash
echo " - $admxZip SHA256: $ADMXSHA"
echo "admx_sha=$ADMXSHA" >> $env:GITHUB_OUTPUT
# Step 6: Create GitHub release with all artifacts
- name: Create release
uses: ncipollo/release-action@b7eabc95ff50cbeeedec83973935c8f306dfcd0b # v1.20.0
if: steps.check_prs.outputs.BUILD_NEEDED == 'true'
with:
tag: v${{ steps.format_version.outputs.NextSemVer }}
commit: ${{ env.BRANCH }}
prerelease: true
generateReleaseNotes: true
name: ${{ steps.format_version.outputs.ReleaseName }}
artifacts: "WAU.msi,${{ steps.build_project.outputs.admx_zip_name }}"
body: |
${{ steps.format_version.outputs.ReleaseBodyIntro }}
⚠️ **Warning**: This build may contain unstable features and is intended for testing purposes only.
## Files
|Files|Hash (SHA256)|Downloads|
|---|---|---|
|[WAU.msi](https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v${{ steps.format_version.outputs.NextSemVer }}/WAU.msi) (x64)|`${{ steps.build_project.outputs.msi_sha }}`|<picture>![WAU.msi](https://img.shields.io/github/downloads/Romanitho/Winget-AutoUpdate/v${{ steps.format_version.outputs.NextSemVer }}/WAU.msi?style=flat-square&label=&color=blue)</picture>|
|[${{ steps.build_project.outputs.admx_zip_name }}](https://github.com/Romanitho/Winget-AutoUpdate/releases/download/v${{ steps.format_version.outputs.NextSemVer }}/${{ steps.build_project.outputs.admx_zip_name }})|`${{ steps.build_project.outputs.admx_sha }}`|<picture>![${{ steps.build_project.outputs.admx_zip_name }}](https://img.shields.io/github/downloads/Romanitho/Winget-AutoUpdate/v${{ steps.format_version.outputs.NextSemVer }}/${{ steps.build_project.outputs.admx_zip_name }}?style=flat-square&label=&color=blue)</picture>|