Skip to content

Nightly & Pre-release Builds #87

Nightly & Pre-release Builds

Nightly & Pre-release Builds #87

Workflow file for this run

name: Nightly & Pre-release Builds
on:
schedule:
# Run every day at 12:00am GMT+8 (16:00 UTC)
- cron: "0 16 * * *"
workflow_dispatch:
inputs:
version:
description: "Version number (e.g., v0.3.3-nightly.20260104) for manual testing"
required: true
type: string
permissions:
contents: write
pull-requests: read
jobs:
# Detect if there are new pushes to main branch AND if last commit is feat or fix
detect-nightly-trigger:
runs-on: ubuntu-latest
outputs:
should_run_nightly: ${{ steps.check.outputs.should_run_nightly }}
commit_type: ${{ steps.check.outputs.commit_type }}
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Check for new pushes and commit type
id: check
run: |
# Get the last commit time
LAST_COMMIT_TIME=$(git log -1 --pretty=%ct)
# Get the current time
CURRENT_TIME=$(date +%s)
# Get the time since last commit (in hours)
HOURS_SINCE_COMMIT=$(( (CURRENT_TIME - LAST_COMMIT_TIME) / 3600 ))
# Get the last commit message
COMMIT_MSG=$(git log -1 --pretty=%B)
echo "Last commit message: $COMMIT_MSG"
# Skip if it's a release commit or merge commit
if [[ "$COMMIT_MSG" == "chore: release"* ]] || [[ "$COMMIT_MSG" == "Merge"* ]]; then
echo "should_run_nightly=false" >> $GITHUB_OUTPUT
exit 0
fi
# Check if commit starts with feat: or fix:
if [[ "$COMMIT_MSG" == "feat:"* ]]; then
COMMIT_TYPE="feature"
elif [[ "$COMMIT_MSG" == "fix:"* ]]; then
COMMIT_TYPE="fix"
else
COMMIT_TYPE="other"
fi
# Only run nightly if last commit is feat or fix AND was pushed within last 24 hours
if [ $HOURS_SINCE_COMMIT -le 24 ] && ([[ "$COMMIT_MSG" == "feat:"* ]] || [[ "$COMMIT_MSG" == "fix:"* ]]); then
echo "should_run_nightly=true" >> $GITHUB_OUTPUT
echo "commit_type=$COMMIT_TYPE" >> $GITHUB_OUTPUT
else
echo "should_run_nightly=false" >> $GITHUB_OUTPUT
echo "commit_type=$COMMIT_TYPE" >> $GITHUB_OUTPUT
fi
# Build nightly installers
build-nightly:
needs: detect-nightly-trigger
if: |
always() &&
(github.event_name == 'workflow_dispatch' ||
needs.detect-nightly-trigger.outputs.should_run_nightly == 'true')
runs-on: windows-latest
timeout-minutes: 30
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Generate nightly version
id: version
run: |
# Check if this is a manual workflow dispatch
if ("${{ github.event_name }}" -eq "workflow_dispatch") {
$version = "${{ inputs.version }}"
Write-Host "📌 Using manual version: $version"
} else {
# Get current date
$date = Get-Date -Format "yyyyMMdd"
# Read base version from pubspec.yaml (e.g. 0.3.3)
$pubspec = Get-Content -Path "pubspec.yaml" -Raw
if ($pubspec -match 'version:\s*([0-9]+\.[0-9]+\.[0-9]+)') {
$baseVersion = $matches[1]
} else {
Write-Error "Unable to read base version from pubspec.yaml"
exit 1
}
# Create version: v0.3.3-nightly.20260102
$version = "v$baseVersion-nightly.$date"
Write-Host "📌 Generated nightly version: $version"
}
echo "VERSION=$version" >> $env:GITHUB_OUTPUT
echo "BUILD_NAME=OverKeys-$version" >> $env:GITHUB_OUTPUT
shell: pwsh
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
channel: "stable"
cache: true
- name: Install InnoSetup
run: |
choco install innosetup -y
Write-Host "✅ InnoSetup installed"
shell: pwsh
- name: Get dependencies
run: flutter pub get
shell: pwsh
- name: Build Flutter Windows app
run: |
.\scripts\ci\build_windows.ps1 -StagingPath "${{ runner.temp }}\inno-staging"
shell: pwsh
- name: Compile InnoSetup installer
run: |
# For nightly builds, we use a different naming scheme
.\scripts\ci\compile_installer.ps1 `
-StagingPath "${{ runner.temp }}\inno-staging" `
-OutputPath "${{ runner.temp }}\output" `
-Version "${{ steps.version.outputs.VERSION }}"
shell: pwsh
- name: Create portable ZIP archive
run: |
Copy-Item -Path "LICENSE" -Destination "${{ runner.temp }}\inno-staging"
.\scripts\ci\compile_zip.ps1 `
-StagingPath "${{ runner.temp }}\inno-staging" `
-OutputPath "${{ runner.temp }}\output" `
-Version "${{ steps.version.outputs.VERSION }}"
shell: pwsh
- name: Fetch Release-Please PR Changelog
id: changelog
run: |
# Find the latest release-please PR (filter by title since it uses PAT)
$prs = @(
(gh pr list `
--repo ${{ github.repository }} `
--search "chore: release in:title" `
--state open `
--json number,body,title `
--limit 1) | ConvertFrom-Json
)
if ($prs.Count -eq 0) {
Write-Host "⚠️ No open release-please PR found, using empty changelog"
$EOF = "EOF_CHANGELOG_$([System.Guid]::NewGuid().ToString())"
Add-Content -Path $env:GITHUB_OUTPUT -Value "CHANGELOG<<$EOF"
Add-Content -Path $env:GITHUB_OUTPUT -Value ""
Add-Content -Path $env:GITHUB_OUTPUT -Value $EOF
exit 0
}
$pr = $prs[0]
$prNumber = $pr.number
$body = $pr.body
Write-Host "ℹ️ Found release-please PR #$prNumber"
Write-Host "🔍 Extracting changelog from PR body..."
# Extract changelog content (everything after "🤖 New release prepared" marker)
if ($body -match '(?s)---\s*\n\s*\n##\s*\[.*?\]\(.*?\)\s*\(.*?\)\s*\n(.+)---\s*\nThis PR was generated') {
$changelog = $matches[1].Trim()
Write-Host "✅ Changelog extracted successfully"
# Replace version number in changelog header with nightly version
$nightlyVersion = "${{ steps.version.outputs.VERSION }}"
$changelog = $changelog -replace '##\s*\[[\d\.]+\]\(https://github\.com/[^/]+/[^/]+/compare/v[\d\.]+(\.\.\.v)?[\d\.]+\)\s*\(\d{4}-\d{2}-\d{2}\)', "## [$nightlyVersion] ($((Get-Date).ToString('yyyy-MM-dd')))"
Write-Host "✅ Updated changelog version to $nightlyVersion"
} else {
Write-Host "⚠️ Could not extract changelog from PR #$prNumber"
$changelog = $body
}
# Save to environment variable using EOF delimiter for multiline content with special characters
$EOF = "EOF_CHANGELOG_$([System.Guid]::NewGuid().ToString())"
Add-Content -Path $env:GITHUB_OUTPUT -Value "CHANGELOG<<$EOF"
Add-Content -Path $env:GITHUB_OUTPUT -Value $changelog
Add-Content -Path $env:GITHUB_OUTPUT -Value $EOF
shell: pwsh
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create pre-release on GitHub
uses: softprops/action-gh-release@v2
with:
files: |
${{ runner.temp }}/output/overkeys_${{ steps.version.outputs.VERSION }}_x64_setup.exe
${{ runner.temp }}/output/overkeys_${{ steps.version.outputs.VERSION }}_x64.zip
tag_name: ${{ steps.version.outputs.VERSION }}
name: "${{ steps.version.outputs.VERSION }}"
body: "${{ steps.changelog.outputs.CHANGELOG }}\n\n### 🐛 Found an issue?\nPlease report it with the nightly version number for faster debugging."
prerelease: true
draft: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Report status
if: always()
run: |
Write-Host "✅ Nightly build completed successfully!"
Write-Host "📦 Pre-release created: ${{ steps.version.outputs.VERSION }}"
shell: pwsh