Skip to content

Build and Publish Patchright .NET #1

Build and Publish Patchright .NET

Build and Publish Patchright .NET #1

# Patchright .NET Build and Publish Workflow
#
# This workflow:
# 1. Checks if a new Playwright .NET version is available
# 2. Checks for the latest compatible Patchright driver version
# 3. Builds the Patchright .NET package
# 4. Creates a GitHub release with the NuGet package
# 5. Publishes to NuGet.org
name: Build and Publish Patchright .NET
on:
# Run daily at 8:00 AM UTC
schedule:
- cron: '0 8 * * *'
# Allow manual trigger with optional force build
workflow_dispatch:
inputs:
force_build:
description: 'Force build even if versions match'
required: false
default: false
type: boolean
driver_update_release:
description: 'Release for driver update only (bumps patch version)'
required: false
default: false
type: boolean
skip_nuget_publish:
description: 'Skip publishing to NuGet.org'
required: false
default: false
type: boolean
# Ensure only one workflow runs at a time
concurrency:
group: build-and-publish
cancel-in-progress: false
env:
DOTNET_VERSION: '10.0.x'
DOTNET_NOLOGO: true
DOTNET_CLI_TELEMETRY_OPTOUT: true
jobs:
# Job 1: Check versions and determine if build is needed
check-versions:
name: Check Versions
runs-on: ubuntu-latest
outputs:
should_build: ${{ steps.compare.outputs.should_build }}
is_driver_update: ${{ steps.compare.outputs.is_driver_update }}
playwright_version: ${{ steps.versions.outputs.playwright_version }}
playwright_major_minor: ${{ steps.versions.outputs.playwright_major_minor }}
patchright_version: ${{ steps.versions.outputs.patchright_version }}
driver_version: ${{ steps.versions.outputs.driver_version }}
driver_available: ${{ steps.versions.outputs.driver_available }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
- name: Compare versions
id: compare
run: |
PLAYWRIGHT="${{ steps.versions.outputs.playwright_version }}"
PATCHRIGHT="${{ steps.versions.outputs.patchright_version }}"
DRIVER="${{ steps.versions.outputs.driver_version }}"
DRIVER_AVAILABLE="${{ steps.versions.outputs.driver_available }}"
PLAYWRIGHT_MAJOR_MINOR="${{ steps.versions.outputs.playwright_major_minor }}"
FORCE="${{ github.event.inputs.force_build }}"
DRIVER_UPDATE="${{ github.event.inputs.driver_update_release }}"
echo "Force build: $FORCE"
echo "Playwright .NET version : $PLAYWRIGHT"
echo "Patchright .NET version : $PATCHRIGHT"
echo "Patchright Driver version : $DRIVER"
echo "Driver available for $PLAYWRIGHT_MAJOR_MINOR: $DRIVER_AVAILABLE"
echo "Driver update release: $DRIVER_UPDATE"
# Function to compare semantic versions
version_gt() {
test "$(printf '%s\n' "$@" | sort -V | head -n 1)" != "$1"
}
# Check if we need to build
NEEDS_BUILD=false
IS_DRIVER_UPDATE=false
if [ "$DRIVER_UPDATE" = "true" ]; then
echo "Driver update release requested - will bump patch version"
NEEDS_BUILD=true
IS_DRIVER_UPDATE=true
elif [ "$FORCE" = "true" ]; then
echo "Force build requested"
NEEDS_BUILD=true
elif version_gt "$PLAYWRIGHT" "$PATCHRIGHT"; then
echo "New Playwright version available: $PLAYWRIGHT > $PATCHRIGHT"
NEEDS_BUILD=true
else
echo "Patchright is up to date"
fi
echo "is_driver_update=$IS_DRIVER_UPDATE" >> $GITHUB_OUTPUT
# If we need to build, verify driver is available
if [ "$NEEDS_BUILD" = "true" ]; then
if [ "$DRIVER_AVAILABLE" != "true" ]; then
echo ""
echo "::error::Cannot build: No compatible Patchright driver found for version $PLAYWRIGHT_MAJOR_MINOR"
echo "::error::The Patchright driver needs to be released for version $PLAYWRIGHT_MAJOR_MINOR.x before we can build."
echo ""
echo "Waiting for driver release at: https://github.com/Kaliiiiiiiiii-Vinyzu/patchright/releases"
echo "should_build=false" >> $GITHUB_OUTPUT
echo "driver_missing=true" >> $GITHUB_OUTPUT
exit 1
else
echo "✓ Compatible driver found: $DRIVER"
echo "should_build=true" >> $GITHUB_OUTPUT
echo "driver_missing=false" >> $GITHUB_OUTPUT
fi
else
echo "should_build=false" >> $GITHUB_OUTPUT
echo "driver_missing=false" >> $GITHUB_OUTPUT
fi
# Job 2: Build the package
build:
name: Build Patchright .NET
needs: check-versions
if: needs.check-versions.outputs.should_build == 'true'
runs-on: windows-latest
outputs:
package_version: ${{ steps.get_version.outputs.version }}
package_path: ${{ steps.find_package.outputs.path }}
package_name: ${{ steps.find_package.outputs.name }}
steps:
- name: Checkout repository
id: checkout
uses: actions/checkout@v4
- name: Setup .NET SDK
id: setup_dotnet
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Run build script
id: build
run: .\build.ps1 -Cleanup -DriverVersion ${{ needs.check-versions.outputs.driver_version }}
- name: Bump patch version for driver update
if: needs.check-versions.outputs.is_driver_update == 'true'
run: |
$versionPropsPath = "playwright-dotnet/src/Common/Version.props"
[xml]$xml = Get-Content $versionPropsPath
# Get current version and bump patch
$currentVersion = $xml.Project.PropertyGroup.AssemblyVersion
$versionParts = $currentVersion -split '\.'
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2] + 1
$newVersion = "$major.$minor.$patch"
Write-Host "Bumping version for driver update: $currentVersion -> $newVersion" -ForegroundColor Cyan
# Update all version elements
$xml.Project.PropertyGroup.AssemblyVersion = $newVersion
$xml.Save($versionPropsPath)
# Rebuild with new version
Write-Host "Rebuilding with new version..." -ForegroundColor Cyan
Push-Location playwright-dotnet
try {
dotnet build --configuration Release ./src/Playwright.sln
dotnet pack --no-build --configuration Release --output ../nuget ./src/Playwright/Playwright.csproj
}
finally {
Pop-Location
}
Write-Host "✓ Version bumped and rebuilt" -ForegroundColor Green
- name: Get package version
id: get_version
run: |
$versionPropsPath = "playwright-dotnet/src/Common/Version.props"
[xml]$xml = Get-Content $versionPropsPath
$version = $xml.Project.PropertyGroup.AssemblyVersion
Write-Host "Package version: $version"
echo "version=$version" >> $env:GITHUB_OUTPUT
- name: Find NuGet package
id: find_package
run: |
$package = Get-ChildItem -Path nuget -Filter "*.nupkg" | Select-Object -First 1
if (-not $package) {
Write-Error "No NuGet package found in nuget directory"
exit 1
}
Write-Host "Found package: $($package.Name)"
echo "path=$($package.FullName)" >> $env:GITHUB_OUTPUT
echo "name=$($package.Name)" >> $env:GITHUB_OUTPUT
- name: Upload NuGet package artifact
id: upload_nuget_package
uses: actions/upload-artifact@v4
with:
name: nuget-package
path: nuget/*.nupkg
retention-days: 30
- name: Upload patch file artifact
id: upload_patch_file
uses: actions/upload-artifact@v4
with:
name: patch-file
path: patchright.patch
retention-days: 30
# Job 3: Create GitHub Release
release:
name: Create GitHub Release
needs: [check-versions, build]
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download NuGet package artifact
uses: actions/download-artifact@v4
with:
name: nuget-package
path: nuget
- name: Download patch file artifact
uses: actions/download-artifact@v4
with:
name: patch-file
path: .
- name: Create GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.build.outputs.package_version }}
name: v${{ needs.build.outputs.package_version }}
body: |
## Patchright .NET v${{ needs.build.outputs.package_version }}
${{ github.event.inputs.skip_nuget_publish == 'true' && '> ⚠️ **NOT PUBLISHED TO NUGET** - This release has not been published to NuGet.org yet. The package is only available as a download from this release.' || format('[![NuGet](https://img.shields.io/nuget/v/Patchright?label=NuGet)](https://www.nuget.org/packages/Patchright/{0})', needs.build.outputs.package_version) }}
${{ needs.check-versions.outputs.is_driver_update == 'true' && '> **Driver Update Release** - This is a patch release to update the Patchright driver version.' || '' }}
This release is based on [Playwright .NET v${{ needs.check-versions.outputs.playwright_version }}](https://github.com/microsoft/playwright-dotnet/releases/tag/v${{ needs.check-versions.outputs.playwright_version }}).
${{ needs.check-versions.outputs.driver_available == 'true' && format('Driver version: {0}', needs.check-versions.outputs.driver_version) || '' }}
### Installation
${{ github.event.inputs.skip_nuget_publish == 'true' && '> ⚠️ This version is not available on NuGet yet. Download the `.nupkg` file from this release to install manually.' || '' }}
```sh
dotnet add package Patchright --version ${{ needs.build.outputs.package_version }}
```
Or via NuGet Package Manager:
```sh
Install-Package Patchright -Version ${{ needs.build.outputs.package_version }}
```
### What's Changed
${{ needs.check-versions.outputs.is_driver_update == 'true' && format('- Driver update release for Playwright .NET v{0}', needs.check-versions.outputs.playwright_version) || format('- Updated to Playwright .NET v{0}', needs.check-versions.outputs.playwright_version) }}
${{ needs.check-versions.outputs.driver_available == 'true' && format('- Updated Patchright driver to v{0}', needs.check-versions.outputs.driver_version) || '' }}
### Files
- `${{ needs.build.outputs.package_name }}` - NuGet package
- `patchright.patch` - Patch file applied to Playwright .NET
files: |
nuget/*.nupkg
patchright.patch
draft: false
prerelease: ${{ github.event.inputs.skip_nuget_publish == 'true' }}
generate_release_notes: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Job 4: Publish to NuGet.org
publish-nuget:
name: Publish to NuGet.org
needs: [build]
if: github.event.inputs.skip_nuget_publish != 'true'
runs-on: ubuntu-latest
steps:
- name: Download NuGet package artifact
uses: actions/download-artifact@v4
with:
name: nuget-package
path: nuget
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Publish to NuGet.org
run: |
PACKAGE=$(ls nuget/*.nupkg | head -1)
echo "Publishing package: $PACKAGE"
dotnet nuget push "$PACKAGE" \
--api-key ${{ secrets.NUGET_API_KEY }} \
--source https://api.nuget.org/v3/index.json \
--skip-duplicate
- name: Publish complete
run: |
echo "✓ Package published to NuGet.org successfully!"
echo "View at: https://www.nuget.org/packages/Patchright"
# Job 5: Notify on failure
notify-failure:
name: Notify on Failure
needs: [check-versions, build, release, publish-nuget]
if: failure()
runs-on: ubuntu-latest
steps:
- name: Create failure issue
uses: actions/github-script@v7
with:
script: |
const title = `Build failed on ${new Date().toISOString().split('T')[0]}`;
const body = `
## Build Failure Report
The automated build workflow failed. Please investigate.
**Workflow Run:** [View Details](${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId})
**Triggered by:** ${context.eventName}
Please check the workflow logs for more details.
`;
// Check if a similar issue already exists
const issues = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
state: 'open',
labels: 'build-failure'
});
const existingIssue = issues.data.find(i => i.title.startsWith('Build failed on'));
if (!existingIssue) {
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: title,
body: body,
labels: ['build-failure', 'automated']
});
}