Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
169 changes: 169 additions & 0 deletions .github/workflows/nightly-preview.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
name: Nightly Preview

on:
schedule:
- cron: '5 10 * * *'
workflow_dispatch:

permissions:
contents: read

defaults:
run:
shell: pwsh

jobs:
check-for-changes:
runs-on: ubuntu-latest
outputs:
changes: ${{ steps.check.outputs.changes }}
steps:
- name: Checkout
uses: actions/checkout@v7
with:
fetch-depth: 0

- name: Check for changes
id: check
run: |
if ($env:GITHUB_EVENT_NAME -eq 'workflow_dispatch') {
Write-Host "Event '$env:GITHUB_EVENT_NAME' detected - forcing build and deployment."
"changes=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
} else {
try {
# Get the latest published package metadata from NuGet registration.
# Avoid [System.Version] parsing because prerelease versions are not compatible with that type.
$packageInfo = Invoke-RestMethod -Uri "https://api.nuget.org/v3/registration5-gz-semver2/intellitect.multitool/index.json"
$registrationPages = @($packageInfo.items)
$registrationItems = @()
foreach ($page in $registrationPages) {
if ($null -ne $page.items) {
$registrationItems += @($page.items)
} elseif ($null -ne $page.'@id') {
$pageResponse = Invoke-RestMethod -Uri $page.'@id'
foreach ($innerPage in @($pageResponse.items)) {
if ($null -ne $innerPage.items) {
$registrationItems += @($innerPage.items)
}
}
}
}

$publishedItems = $registrationItems | Where-Object { $null -ne $_.catalogEntry -and $null -ne $_.catalogEntry.published }
if (-not $publishedItems) {
throw "No published package entries were found in NuGet registration feed."
}

$latestPublishedItem = $publishedItems | Sort-Object { [DateTimeOffset]::Parse($_.catalogEntry.published).UtcDateTime } | Select-Object -Last 1
$lastPublishedDate = [DateTimeOffset]::Parse($latestPublishedItem.catalogEntry.published).UtcDateTime
Write-Host "Latest NuGet package version: $($latestPublishedItem.catalogEntry.version)"
Write-Host "Last published date (UTC): $lastPublishedDate"

# Get the latest commit date.
$latestCommitDate = [DateTimeOffset]::Parse((git log -1 --format=%cI)).UtcDateTime
Write-Host "Latest commit date (UTC): $latestCommitDate"

# Check if there are commits newer than the last published package
if ($latestCommitDate -gt $lastPublishedDate) {
Write-Host "Repository has changes newer than the last published package"
"changes=true" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
} else {
Write-Host "No changes since last published package"
"changes=false" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append
}
} catch {
Write-Error "Failed to determine NuGet publish state for nightly deploy: $($_.Exception.Message)"
throw
}
}

build-test-pack:
if: needs.check-for-changes.outputs.changes == 'true'
name: Build, Test, and Pack
runs-on: ubuntu-latest
needs: check-for-changes
outputs:
nugetVersion: ${{ steps.set-version.outputs.nugetVersion }}
steps:
- uses: actions/checkout@v7
with:
fetch-depth: 0
fetch-tags: true

- name: Setup .NET
uses: actions/setup-dotnet@v6
with:
global-json-file: global.json

- name: Restore dependencies
run: dotnet restore

- name: Set Version
id: set-version
run: |
git fetch --tags
$tagVersion = & git describe --tags --abbrev=0 2>$null
if (-not $tagVersion) {
$tagVersion = "v0.0.0"
}

# Remove 'v' or 'V' prefix if present for NuGet version compatibility
if ($tagVersion.StartsWith("v") -or $tagVersion.StartsWith("V")) {
$tagVersion = $tagVersion.Substring(1)
}

# Increment patch version for nightly preview releases
$versionParts = $tagVersion.Split('.')
if ($versionParts.Length -ge 3) {
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2] + 1
$tagVersion = "$major.$minor.$patch"
}

$date = Get-Date -AsUTC -Format "yyyyMMdd"
$nugetVersion = "$tagVersion-preview.$date.${{ github.run_number }}"
$buildVersion = "$tagVersion.${{ github.run_number }}"

echo "buildVersion=$buildVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "nugetVersion=$nugetVersion" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
echo "nugetVersion=$nugetVersion" | Out-File -FilePath $env:GITHUB_OUTPUT -Encoding utf8 -Append

- name: Build
run: dotnet build -p:Version=${{ env.buildVersion }} -p:ReleaseDateAttribute=true -p:ContinuousIntegrationBuild=True --no-restore --configuration Release

- name: Test
run: dotnet test --no-build --configuration Release --verbosity normal

- name: Pack
run: dotnet pack -p:PackageVersion=${{ env.nugetVersion }} --configuration Release -o ${{ github.workspace }}/IntelliTect.MultitoolPack --no-build

- name: Upload Artifacts
uses: actions/upload-artifact@v7
with:
name: NuGet
path: ${{ github.workspace }}/IntelliTect.MultitoolPack

deploy:
if: needs.check-for-changes.outputs.changes == 'true'
runs-on: ubuntu-latest
needs: [check-for-changes, build-test-pack]
environment:
name: 'Production'
url: 'https://www.nuget.org/packages/IntelliTect.Multitool'
permissions:
id-token: write # Required for OIDC token (NuGet trusted publishing)
steps:
- name: Download artifact from build job
uses: actions/download-artifact@v8
with:
name: NuGet

- name: NuGet login
uses: NuGet/login@v1
id: login
with:
user: ${{ secrets.NUGET_USER }}

- name: Push NuGet
run: dotnet nuget push IntelliTect.Multitool.${{ needs.build-test-pack.outputs.nugetVersion }}.nupkg --source https://api.nuget.org/v3/index.json --api-key ${{ steps.login.outputs.NUGET_API_KEY }} --skip-duplicate
Loading