From 115891ebee72ddd301f56b9afd49aa1ac5c693d5 Mon Sep 17 00:00:00 2001 From: AutomatedTester Date: Wed, 7 Oct 2026 15:11:47 +0100 Subject: [PATCH] [javascript] Publish @seleniumhq/atoms as part of the npm release MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The npm package landed in #17459 but nothing published it. Wire it into the existing Node release path alongside selenium-webdriver. * node:release publishes //javascript/atoms:selenium-atoms-package.publish before selenium-webdriver.publish. The "already published" rescue is extracted into publish_npm_package so both share it. * node:verify checks both packages; node:build builds both. * setup_github_npm_auth redirects the atoms registry for the nightly GitHub Packages path. The name is already scoped so it needs no rename, but the npmjs access flag is stripped — GitHub Packages derives visibility from the repository. * Add publishConfig.access: public to javascript/atoms/package.json. Scoped packages default to restricted on npmjs, so without this the first publish is rejected. * node:version now fails if the two versions have drifted. The bump works by substituting old_version, so drift would silently leave atoms stale and only surface as a node:verify failure after the release shipped. * Convert the path/target literals to methods rather than constants. Rakefile loads this file twice (as node: and aliased as javascript:), which made constants warn on every invocation. ./go javascript:release dry-run passes end to end for both packages. --- javascript/atoms/package.json | 4 ++ rake_tasks/node.rake | 86 +++++++++++++++++++++++++++-------- 2 files changed, 70 insertions(+), 20 deletions(-) diff --git a/javascript/atoms/package.json b/javascript/atoms/package.json index 2794814b10972..a5828e201d250 100644 --- a/javascript/atoms/package.json +++ b/javascript/atoms/package.json @@ -47,5 +47,9 @@ "url": "https://github.com/SeleniumHQ/selenium.git", "directory": "javascript/atoms" }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, "license": "Apache-2.0" } diff --git a/rake_tasks/node.rake b/rake_tasks/node.rake index 57327b1beb806..e1ae9492225d2 100644 --- a/rake_tasks/node.rake +++ b/rake_tasks/node.rake @@ -1,11 +1,49 @@ # frozen_string_literal: true -def node_version - File.foreach('javascript/selenium-webdriver/package.json') do |line| +# This file is loaded twice — once as `node:`, once aliased as `javascript:` — +# so these are methods rather than constants to avoid redefinition warnings. +def webdriver_package_json + 'javascript/selenium-webdriver/package.json' +end + +def atoms_package_json + 'javascript/atoms/package.json' +end + +def webdriver_publish_target + '//javascript/selenium-webdriver:selenium-webdriver.publish' +end + +def atoms_publish_target + '//javascript/atoms:selenium-atoms-package.publish' +end + +def package_json_version(path) + File.foreach(path) do |line| return line.split(':').last.strip.tr('",', '') if line.include?('version') end end +def node_version + package_json_version(webdriver_package_json) +end + +def atoms_version + package_json_version(atoms_package_json) +end + +def publish_npm_package(target, config, dry_run) + bazel_args = ["--config=#{config}"] + bazel_args += ['--', '--dry-run=true'] if dry_run + + Bazel.execute('run', bazel_args, target) +rescue RuntimeError => e + raise if dry_run + raise unless e.message.match?(/cannot publish over the previously published/i) + + puts "#{target} version already published — skipping." +end + def setup_github_npm_auth token = ENV.fetch('GITHUB_TOKEN', nil) raise 'Missing GitHub token: set GITHUB_TOKEN for nightly npm publish' if token.nil? || token.empty? @@ -26,16 +64,24 @@ def setup_github_npm_auth File.chmod(0o600, npmrc) # Update package.json for GitHub Packages - package_json = 'javascript/selenium-webdriver/package.json' - content = File.read(package_json) + content = File.read(webdriver_package_json) content = content.gsub('https://registry.npmjs.org/', 'https://npm.pkg.github.com') content = content.gsub('"name": "selenium-webdriver"', '"name": "@seleniumhq/selenium-webdriver"') - File.write(package_json, content) + File.write(webdriver_package_json, content) + + # @seleniumhq/atoms is already scoped, so only the registry needs redirecting. + # GitHub Packages derives visibility from the repository, so drop the npmjs + # access flag rather than send one it does not honour. + content = File.read(atoms_package_json) + content = content.gsub('https://registry.npmjs.org/', 'https://npm.pkg.github.com') + content = content.gsub(/^\s*"access": "public",\n/, '') + File.write(atoms_package_json, content) end -desc 'Build Node npm package' +desc 'Build Node npm packages' task :build do |_task, arguments| args = arguments.to_a + Bazel.execute('build', args, '//javascript/atoms:selenium-atoms-package') Bazel.execute('build', args, '//javascript/selenium-webdriver') end @@ -87,7 +133,7 @@ task :release do |_task, arguments| end if already_published - puts 'Node package already published — skipping release.' + puts 'Node packages already published — skipping release.' next end end @@ -101,23 +147,16 @@ task :release do |_task, arguments| end puts dry_run ? 'Running Node package dry-run...' : 'Running Node package release...' - target = '//javascript/selenium-webdriver:selenium-webdriver.publish' - bazel_args = ["--config=#{config}"] - bazel_args += ['--', '--dry-run=true'] if dry_run - - begin - Bazel.execute('run', bazel_args, target) - rescue RuntimeError => e - raise if dry_run - raise unless e.message.match?(/cannot publish over the previously published/i) - - puts 'npm package version already published — skipping.' - end + # @seleniumhq/atoms publishes first so the lower-level package is on the + # registry before anything that may start depending on it. + publish_npm_package(atoms_publish_target, config, dry_run) + publish_npm_package(webdriver_publish_target, config, dry_run) end -desc 'Verify Node package is published on npm' +desc 'Verify Node packages are published on npm' task :verify do SeleniumRake.verify_package_published("https://registry.npmjs.org/selenium-webdriver/#{node_version}") + SeleniumRake.verify_package_published("https://registry.npmjs.org/@seleniumhq%2Fatoms/#{atoms_version}") end desc 'Alias for node:release' @@ -156,6 +195,13 @@ end desc 'Update Node version' task :version, [:version] do |_task, arguments| old_version = node_version + # Both packages are bumped by substituting old_version, so a drifted + # @seleniumhq/atoms would silently keep its stale version and then fail + # `node:verify` after the release has already gone out. + if atoms_version != old_version + raise "Version mismatch: selenium-webdriver is #{old_version} but @seleniumhq/atoms is #{atoms_version}" + end + nightly = "-nightly#{Time.now.strftime('%Y%m%d%H%M')}" new_version = SeleniumRake.updated_version(old_version, arguments[:version], nightly) puts "Updating Node from #{old_version} to #{new_version}"