diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a4dfbdf..3a82fe8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -201,6 +201,10 @@ jobs: fi echo "All 5 platform binaries present and valid" + - name: Verify bundled binary versions + run: | + pnpm run verify:bundled-binaries + - name: Create Release Pull Request or Publish to npm id: changesets uses: changesets/action@v1 diff --git a/cli/Cargo.toml b/cli/Cargo.toml index 34c8a75..853d0ec 100644 --- a/cli/Cargo.toml +++ b/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "agent-browser-stealth" -version = "0.16.1-fork.1" +version = "0.16.1-fork.2" edition = "2021" description = "Stealth browser automation CLI for AI agents with anti-bot evasions" license = "Apache-2.0" diff --git a/package.json b/package.json index bca0142..2ef4b1b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "agent-browser-stealth", - "version": "0.16.1-fork.1", + "version": "0.16.1-fork.2", "description": "Stealth browser automation CLI for AI agents with anti-bot evasions", "type": "module", "main": "dist/daemon.js", @@ -27,7 +27,7 @@ "build:windows": "npm run version:sync && docker compose -f docker/docker-compose.yml run --rm build-windows", "build:all-platforms": "npm run version:sync && (npm run build:linux & npm run build:windows & wait) && npm run build:macos", "build:docker": "docker build -t agent-browser-builder -f docker/Dockerfile.build .", - "release": "npm run version:sync && npm run build && npm run build:all-platforms && npm publish", + "release": "npm run version:sync && npm run build && npm run build:all-platforms && npm run verify:bundled-binaries && npm run verify:native-version && npm publish", "start": "node dist/daemon.js", "dev": "tsx src/daemon.ts", "typecheck": "tsc --noEmit", @@ -41,12 +41,13 @@ "check:turnstile-testkey": "pnpm exec tsx scripts/check-turnstile-testkey.ts", "postinstall": "node scripts/postinstall.js", "verify:native-version": "node scripts/verify-native-version.js", + "verify:bundled-binaries": "node scripts/verify-bundled-binaries.js", "clawhub:sync": "bash scripts/clawhub-sync.sh", "sync:upstream": "bash scripts/sync-upstream.sh", "sync:upstream:push": "bash scripts/sync-upstream.sh --push", "changeset": "changeset", "ci:version": "changeset version && pnpm run version:sync && pnpm install --no-frozen-lockfile", - "ci:publish": "pnpm run version:sync && pnpm run build && pnpm run build:native && pnpm run verify:native-version && changeset publish" + "ci:publish": "pnpm run version:sync && pnpm run build && pnpm run build:native && pnpm run verify:bundled-binaries && pnpm run verify:native-version && changeset publish" }, "keywords": [ "browser", diff --git a/scripts/verify-bundled-binaries.js b/scripts/verify-bundled-binaries.js new file mode 100644 index 0000000..40c8b70 --- /dev/null +++ b/scripts/verify-bundled-binaries.js @@ -0,0 +1,71 @@ +#!/usr/bin/env node + +/** + * Verifies that all bundled platform binaries are present and embed the + * package.json version string. This catches stale binary bundles where the + * package version is bumped but one or more binaries were not rebuilt. + */ + +import { existsSync, readFileSync, statSync } from "fs"; +import { dirname, join } from "path"; +import { fileURLToPath } from "url"; + +const __dirname = dirname(fileURLToPath(import.meta.url)); +const rootDir = join(__dirname, ".."); + +const pkg = JSON.parse(readFileSync(join(rootDir, "package.json"), "utf8")); +const expectedVersion = String(pkg.version || "").trim(); + +if (!expectedVersion) { + console.error("Error: package.json version is empty"); + process.exit(1); +} + +const expectedBinaries = [ + "agent-browser-linux-x64", + "agent-browser-linux-arm64", + "agent-browser-win32-x64.exe", + "agent-browser-darwin-x64", + "agent-browser-darwin-arm64", +]; + +const minSizeBytes = 100_000; +const versionBytes = Buffer.from(expectedVersion, "utf8"); + +let errors = 0; + +for (const name of expectedBinaries) { + const binaryPath = join(rootDir, "bin", name); + if (!existsSync(binaryPath)) { + console.error(`ERROR: missing binary: bin/${name}`); + errors += 1; + continue; + } + + const size = statSync(binaryPath).size; + if (size < minSizeBytes) { + console.error( + `ERROR: binary too small: bin/${name} (${size} bytes, expected >= ${minSizeBytes})` + ); + errors += 1; + continue; + } + + const bytes = readFileSync(binaryPath); + if (!bytes.includes(versionBytes)) { + console.error( + `ERROR: stale binary version: bin/${name} does not contain "${expectedVersion}"` + ); + errors += 1; + continue; + } + + console.log(`OK: bin/${name} matches version ${expectedVersion}`); +} + +if (errors > 0) { + console.error(`\nFound ${errors} binary validation issue(s).`); + process.exit(1); +} + +console.log(`\nAll bundled binaries match package.json version ${expectedVersion}.`);