Build and Publish Patchright .NET #88
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
| # 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('[](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 | |
| }); | |
| } |