GitFlow | Nightly Builds #290
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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></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></picture>| |