Skip to content

Build and Publish Patchright .NET #82

Build and Publish Patchright .NET

Build and Publish Patchright .NET #82

# Patchright .NET Build and Publish Workflow
#
# This workflow:
# 1. Always builds the package (CI validation)
# 2. Creates/updates GitHub release (unless version already published to NuGet)
# 3. Optionally publishes to NuGet.org
#
# Behavior:
# - Build: Always runs to validate the build
# - Release: Created/updated unless version exists on NuGet (published = immutable)
# - Publish: Only when nuget_publish=true AND version doesn't exist on NuGet
# - Driver update: Bumps patch version, same rules apply
name: Build and Publish Patchright .NET
on:
# Run daily at 8:00 AM UTC
schedule:
- cron: '0 8 * * *'
# Allow manual trigger
workflow_dispatch:
inputs:
driver_update_release:
description: 'Release for driver update only (bumps patch version)'
required: false
default: false
type: boolean
nuget_publish:
description: 'Publish 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: Determine versions and check NuGet status
check-versions:
name: Check Versions
runs-on: ubuntu-latest
outputs:
target_version: ${{ steps.decide.outputs.target_version }}
nuget_exists: ${{ steps.decide.outputs.nuget_exists }}
is_driver_update: ${{ steps.decide.outputs.is_driver_update }}
playwright_version: ${{ steps.versions.outputs.playwright_version }}
driver_version: ${{ steps.versions.outputs.driver_version }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Get versions
id: versions
uses: ./.github/actions/get-versions
- name: Determine target version
id: decide
run: |
PLAYWRIGHT='${{ steps.versions.outputs.playwright_version }}'
PATCHRIGHT='${{ steps.versions.outputs.patchright_version }}'
NUGET_VERSION='${{ steps.versions.outputs.nuget_version }}'
NUGET_VERSIONS='${{ steps.versions.outputs.nuget_versions }}'
DRIVER='${{ steps.versions.outputs.driver_version }}'
DRIVER_AVAILABLE='${{ steps.versions.outputs.driver_available }}'
PLAYWRIGHT_MAJOR_MINOR='${{ steps.versions.outputs.playwright_major_minor }}'
IS_DRIVER_UPDATE='${{ github.event.inputs.driver_update_release }}'
echo "=== Version Info ==="
echo "Playwright .NET : $PLAYWRIGHT"
echo "Patchright GitHub : $PATCHRIGHT"
echo "Patchright NuGet : $NUGET_VERSION"
echo "Patchright Driver : $DRIVER"
echo "Driver available : $DRIVER_AVAILABLE"
echo ""
# Function to bump patch version
bump_patch() {
local version=$1
local major minor patch
IFS='.' read -r major minor patch <<< "$version"
echo "$major.$minor.$((patch + 1))"
}
# Determine target version
if [ "$IS_DRIVER_UPDATE" = "true" ]; then
if [ -n "$NUGET_VERSION" ] && [ "$NUGET_VERSION" != "" ]; then
TARGET_VERSION=$(bump_patch "$NUGET_VERSION")
echo "Driver update: $NUGET_VERSION -> $TARGET_VERSION"
else
echo "::error::Cannot do driver update: no existing NuGet version found"
exit 1
fi
else
TARGET_VERSION="$PLAYWRIGHT"
echo "Target version: $TARGET_VERSION"
fi
# Check if driver is available
if [ "$DRIVER_AVAILABLE" != "true" ]; then
echo ""
echo "::error::Cannot build: No compatible Patchright driver found for version $PLAYWRIGHT_MAJOR_MINOR"
echo "Waiting for driver release at: https://github.com/Kaliiiiiiiiii-Vinyzu/patchright/releases"
exit 1
fi
# Check if target version already exists on NuGet
NUGET_EXISTS=false
echo "Checking if $TARGET_VERSION exists in NuGet versions..."
echo "NuGet versions JSON: $NUGET_VERSIONS"
# Validate JSON is not empty
if [ -z "$NUGET_VERSIONS" ] || [ "$NUGET_VERSIONS" = "[]" ]; then
echo "No versions found on NuGet.org"
else
# Check if version exists in the array
if echo "$NUGET_VERSIONS" | jq -e --arg ver "$TARGET_VERSION" 'any(. == $ver)' > /dev/null 2>&1; then
echo "Version $TARGET_VERSION exists on NuGet.org (release is immutable)"
NUGET_EXISTS=true
else
echo "Version $TARGET_VERSION not on NuGet.org"
fi
fi
echo ""
echo "Target version : $TARGET_VERSION"
echo "NuGet exists : $NUGET_EXISTS"
echo "target_version=$TARGET_VERSION" >> $GITHUB_OUTPUT
echo "nuget_exists=$NUGET_EXISTS" >> $GITHUB_OUTPUT
echo "is_driver_update=$IS_DRIVER_UPDATE" >> $GITHUB_OUTPUT
# Job 2: Build the package (always runs)
build:
name: Build Patchright .NET
needs: check-versions
runs-on: windows-latest
outputs:
package_version: ${{ needs.check-versions.outputs.target_version }}
package_name: ${{ steps.find_package.outputs.name }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Setup .NET SDK
uses: actions/setup-dotnet@v4
with:
dotnet-version: ${{ env.DOTNET_VERSION }}
- name: Run build script
run: |
$targetVersion = "${{ needs.check-versions.outputs.target_version }}"
$driverVersion = "${{ needs.check-versions.outputs.driver_version }}"
Write-Host "Building Patchright .NET v$targetVersion with driver v$driverVersion" -ForegroundColor Cyan
.\build.ps1 -Cleanup -DriverVersion $driverVersion -PackageVersion $targetVersion -IsolatedContext $True
- 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 "name=$($package.Name)" >> $env:GITHUB_OUTPUT
# Artifacts are temporary storage for passing files between jobs.
# They are NOT the same as release assets - release assets are permanent.
# These expire after 1 day, but the files attached to GitHub releases stay forever.
- name: Upload NuGet package artifact
uses: actions/upload-artifact@v4
with:
name: nuget-package
path: nuget/*.nupkg
retention-days: 1
- name: Upload patch file artifact
uses: actions/upload-artifact@v4
with:
name: patch-file
path: patchright.patch
retention-days: 1
# Job 3: Create/Update GitHub Release (skip if version already published to NuGet)
release:
name: Create GitHub Release
needs: [check-versions, build]
if: needs.check-versions.outputs.nuget_exists != 'true'
runs-on: ubuntu-latest
permissions:
contents: write
steps:
- name: Download artifacts
uses: actions/download-artifact@v4
with:
path: artifacts
- name: Create/Update GitHub Release
uses: softprops/action-gh-release@v2
with:
tag_name: v${{ needs.check-versions.outputs.target_version }}
name: v${{ needs.check-versions.outputs.target_version }}
body: |
## Patchright .NET v${{ needs.check-versions.outputs.target_version }}
${{ github.event.inputs.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.check-versions.outputs.target_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 }}).
Driver version: ${{ needs.check-versions.outputs.driver_version }}
### Installation
${{ github.event.inputs.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.check-versions.outputs.target_version }}
```
Or via NuGet Package Manager:
```sh
Install-Package Patchright -Version ${{ needs.check-versions.outputs.target_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) }}
- Updated Patchright driver to v${{ needs.check-versions.outputs.driver_version }}
### Files
- `patchright.patch` - Patch file applied to Playwright .NET
${{ github.event.inputs.nuget_publish != 'true' && format('- `{0}` - NuGet package', needs.build.outputs.package_name) || '' }}
files: |
artifacts/nuget-package/*.nupkg
artifacts/patch-file/patchright.patch
draft: false
prerelease: ${{ github.event.inputs.nuget_publish != 'true' }}
make_latest: ${{ github.event.inputs.nuget_publish == 'true' }}
generate_release_notes: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Job 4: Publish to NuGet.org (only if requested AND version doesn't exist)
publish-nuget:
name: Publish to NuGet.org
needs: [check-versions, build]
if: github.event.inputs.nuget_publish == 'true' && needs.check-versions.outputs.nuget_exists != 'true'
runs-on: ubuntu-latest
steps:
- name: Download NuGet package
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
echo "✓ Package published to NuGet.org!"
echo "View at: https://www.nuget.org/packages/Patchright/${{ needs.check-versions.outputs.target_version }}"
# Remove the .nupkg from the release (it's 190MB+) - users can get it from NuGet.org
- name: Remove .nupkg from GitHub Release
uses: actions/github-script@v7
with:
script: |
const tag = 'v${{ needs.check-versions.outputs.target_version }}';
const { data: release } = await github.rest.repos.getReleaseByTag({
owner: context.repo.owner,
repo: context.repo.repo,
tag
});
for (const asset of release.assets.filter(a => a.name.endsWith('.nupkg'))) {
console.log(`Deleting ${asset.name} from release ${tag}`);
await github.rest.repos.deleteReleaseAsset({
owner: context.repo.owner,
repo: context.repo.repo,
asset_id: asset.id
});
}