1#!/usr/bin/env nix-shell 2#!nix-shell -i bash -p curl gnused common-updater-scripts jq prefetch-npm-deps unzip nix-prefetch 3set -euo pipefail 4 5root="$(dirname "$(readlink -f "$0")")" 6 7version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s https://api.github.com/repos/microsoft/playwright-python/releases/latest | jq -r '.tag_name | sub("^v"; "")') 8# Most of the time, this should be the latest stable release of the Node-based 9# Playwright version, but that isn't a guarantee, so this needs to be specified 10# as well: 11setup_py_url="https://github.com/microsoft/playwright-python/raw/v${version}/setup.py" 12driver_version=$(curl -Ls "$setup_py_url" | grep '^driver_version =' | grep -Eo '[0-9]+\.[0-9]+\.[0-9]+') 13 14# TODO: skip if update-source-version reported the same version 15update-source-version playwright-driver "$driver_version" 16update-source-version python3Packages.playwright "$version" 17 18playwright_dir="$root/../../web/playwright" 19driver_file="$playwright_dir/driver.nix" 20repo_url_prefix="https://github.com/microsoft/playwright/raw" 21 22temp_dir=$(mktemp -d) 23trap 'rm -rf "$temp_dir"' EXIT 24 25# Update playwright-mcp package 26mcp_version=$(curl ${GITHUB_TOKEN:+" -u \":$GITHUB_TOKEN\""} -s https://api.github.com/repos/microsoft/playwright-mcp/releases/latest | jq -r '.tag_name | sub("^v"; "")') 27update-source-version playwright-mcp "$mcp_version" 28 29# Update npmDepsHash for playwright-mcp 30pushd "$temp_dir" >/dev/null 31curl -fsSL -o package-lock.json "https://raw.githubusercontent.com/microsoft/playwright-mcp/v${mcp_version}/package-lock.json" 32mcp_npm_hash=$(prefetch-npm-deps package-lock.json) 33rm -f package-lock.json 34popd >/dev/null 35 36mcp_package_file="$root/../../../by-name/pl/playwright-mcp/package.nix" 37sed -E 's#\bnpmDepsHash = ".*?"#npmDepsHash = "'"$mcp_npm_hash"'"#' -i "$mcp_package_file" 38 39 40# update binaries of browsers, used by playwright. 41replace_sha() { 42 sed -i "s|$2 = \".\{44,52\}\"|$2 = \"$3\"|" "$1" 43} 44 45prefetch_browser() { 46 # nix-prefetch is used to obtain sha with `stripRoot = false` 47 # doesn't work on macOS https://github.com/msteen/nix-prefetch/issues/53 48 nix-prefetch --option extra-experimental-features flakes -q "{ stdenv, fetchzip }: stdenv.mkDerivation { name=\"browser\"; src = fetchzip { url = \"$1\"; stripRoot = $2; }; }" 49} 50 51update_browser() { 52 name="$1" 53 platform="$2" 54 stripRoot="false" 55 if [ "$platform" = "darwin" ]; then 56 if [ "$name" = "webkit" ]; then 57 suffix="mac-14" 58 else 59 suffix="mac" 60 fi 61 else 62 if [ "$name" = "ffmpeg" ] || [ "$name" = "chromium-headless-shell" ]; then 63 suffix="linux" 64 elif [ "$name" = "chromium" ]; then 65 stripRoot="true" 66 suffix="linux" 67 elif [ "$name" = "firefox" ]; then 68 stripRoot="true" 69 suffix="ubuntu-22.04" 70 else 71 suffix="ubuntu-22.04" 72 fi 73 fi 74 aarch64_suffix="$suffix-arm64" 75 if [ "$name" = "chromium-headless-shell" ]; then 76 buildname="chromium"; 77 else 78 buildname="$name" 79 fi 80 81 revision="$(jq -r ".browsers[\"$buildname\"].revision" "$playwright_dir/browsers.json")" 82 replace_sha "$playwright_dir/$name.nix" "x86_64-$platform" \ 83 "$(prefetch_browser "https://playwright.azureedge.net/builds/$buildname/$revision/$name-$suffix.zip" $stripRoot)" 84 replace_sha "$playwright_dir/$name.nix" "aarch64-$platform" \ 85 "$(prefetch_browser "https://playwright.azureedge.net/builds/$buildname/$revision/$name-$aarch64_suffix.zip" $stripRoot)" 86} 87 88curl -fsSl \ 89 "https://raw.githubusercontent.com/microsoft/playwright/v${driver_version}/packages/playwright-core/browsers.json" \ 90 | jq ' 91 .comment = "This file is kept up to date via update.sh" 92 | .browsers |= ( 93 [.[] 94 | select(.installByDefault) | del(.installByDefault)] 95 | map({(.name): . | del(.name)}) 96 | add 97 ) 98 ' > "$playwright_dir/browsers.json" 99 100update_browser "chromium" "linux" 101update_browser "chromium-headless-shell" "linux" 102update_browser "firefox" "linux" 103update_browser "webkit" "linux" 104update_browser "ffmpeg" "linux" 105 106update_browser "chromium" "darwin" 107update_browser "chromium-headless-shell" "darwin" 108update_browser "firefox" "darwin" 109update_browser "webkit" "darwin" 110update_browser "ffmpeg" "darwin" 111 112# Update package-lock.json files for all npm deps that are built in playwright 113 114# Function to download `package-lock.json` for a given source path and update hash 115update_hash() { 116 local source_root_path="$1" 117 local existing_hash="$2" 118 119 # Formulate download URL 120 local download_url="${repo_url_prefix}/v${driver_version}${source_root_path}/package-lock.json" 121 # Download package-lock.json to temporary directory 122 curl -fsSL -o "${temp_dir}/package-lock.json" "$download_url" 123 124 # Calculate the new hash 125 local new_hash 126 new_hash=$(prefetch-npm-deps "${temp_dir}/package-lock.json") 127 128 # Update npmDepsHash in the original file 129 sed -i "s|$existing_hash|${new_hash}|" "$driver_file" 130} 131 132while IFS= read -r source_root_line; do 133 [[ "$source_root_line" =~ sourceRoot ]] || continue 134 source_root_path=$(echo "$source_root_line" | sed -e 's/^.*"${src.name}\(.*\)";.*$/\1/') 135 # Extract the current npmDepsHash for this sourceRoot 136 existing_hash=$(grep -A1 "$source_root_line" "$driver_file" | grep 'npmDepsHash' | sed -e 's/^.*npmDepsHash = "\(.*\)";$/\1/') 137 138 # Call the function to download and update the hash 139 update_hash "$source_root_path" "$existing_hash" 140done < "$driver_file"