Skip to content

Commit ea4e64a

Browse files
authored
Merge pull request #37 from browserstack/migration/monorepo-add-wdio-browserstack-service
feat: monorepo conversion — add @wdio/browserstack-service alongside the gRPC core
2 parents f1c3688 + 2ad7617 commit ea4e64a

161 files changed

Lines changed: 50459 additions & 733 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Changesets
2+
3+
This repo uses [Changesets](https://github.com/changesets/changesets) to version and publish
4+
**`@wdio/browserstack-service`** on BrowserStack's own cadence (independent of WebdriverIO's
5+
release schedule).
6+
7+
- Add a changeset for any user-facing change: `npm run changeset` (pick patch/minor/major).
8+
- On merge to `main` (the v9 line) or `v8` (the v8 line), the Release workflow opens a
9+
"Version Packages" PR; merging that PR publishes to npm via OIDC trusted publishing.
10+
- The gRPC/protobuf client is generated inline from the bundled `.proto` files at build time
11+
(`buf generate`) — it is no longer a separate workspace package, so `config.json` `ignore` is
12+
empty and there is nothing extra for this pipeline to skip.

.changeset/config.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
3+
"changelog": "@changesets/cli/changelog",
4+
"commit": false,
5+
"fixed": [],
6+
"linked": [],
7+
"access": "public",
8+
"baseBranch": "main",
9+
"updateInternalDependencies": "patch",
10+
"ignore": [],
11+
"snapshot": {
12+
"useCalculatedVersion": true
13+
}
14+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wdio/browserstack-service": patch
3+
---
4+
5+
Declare `webdriverio` as a dependency instead of a peerDependency, matching the package published from the WebdriverIO monorepo. The extraction had moved `webdriverio` into `peerDependencies` (`^9.0.0`); npm then forced the consumer's `webdriverio` to `^9`, which conflicts with any project that also depends on a package peering `webdriverio@"^7 || ^8"` (e.g. `wdio-chromedriver-service@^8`) and surfaced as an `npm ERESOLVE` on install — a failure the monorepo-published package never had. Restores install parity with the upstream package; no user-facing API change.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wdio/browserstack-service": patch
3+
---
4+
5+
Port the 2026-07-10 monorepo accessibility/CLI fixes to keep the standalone at parity (webdriverio/webdriverio#15380, #15383, #15382, #15381, #15376): skip the accessibility scan for BiDi `window`/`context` commands, route WDIO CLI-flow App Automate sessions to app-accessibility, finalize orphaned test runs on an interrupted exit, coerce stringified boolean accessibility options, and report mocha hooks in the CLI/testHub flow. No user-facing API change.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wdio/browserstack-service": minor
3+
---
4+
5+
Publish from the standalone `browserstack/wdio-browserstack-service` repo, at parity with the WebdriverIO monorepo. Includes Load Testing Service (LTS) support, one-to-many Test-Case-ID tagging (`setCustomTestCaseId`), correct test/hook finish on mocha timeouts, per-batch failure isolation in the request queue, accessibility Browser type augmentations, and `yauzl` upgraded to `^3.4.0`. No user-facing API change.

.changeset/take-over-publishing.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
"@wdio/browserstack-service": minor
3+
---
4+
5+
BrowserStack now publishes `@wdio/browserstack-service` from its own repository
6+
(`browserstack/wdio-browserstack-service`) on an independent release cadence, using npm OIDC
7+
trusted publishing. No change for end users — same package name and the same
8+
`services: ['browserstack']` configuration continue to work unchanged.

.eslintrc.cjs

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
/** @type {import('eslint').Linter.Config} */
2+
// Ported from the WebdriverIO monorepo (.eslintrc.cjs) so the standalone repo lints
3+
// @wdio/browserstack-service with the same rules it had upstream. ignorePatterns adds the
4+
// build output and the buf-generated gRPC stubs (src/grpc/generated), which are not authored here.
5+
const config = {
6+
root: true,
7+
parser: '@typescript-eslint/parser',
8+
plugins: ['@typescript-eslint', 'unicorn', 'import'],
9+
extends: ['eslint:recommended'],
10+
env: {
11+
node: true,
12+
es6: true,
13+
},
14+
parserOptions: {
15+
ecmaVersion: 2020,
16+
sourceType: 'module',
17+
},
18+
ignorePatterns: [
19+
'**/node_modules/**',
20+
'**/build/**',
21+
'**/generated/**',
22+
'**/*.d.ts',
23+
],
24+
rules: {
25+
quotes: ['error', 'single', { avoidEscape: true }],
26+
camelcase: ['error', { properties: 'never' }],
27+
semi: ['error', 'never'],
28+
indent: [2, 4],
29+
eqeqeq: ['error', 'always'],
30+
31+
'prefer-const': 'error',
32+
'no-multiple-empty-lines': [2, { max: 1, maxEOF: 1 }],
33+
'array-bracket-spacing': ['error', 'never'],
34+
'brace-style': ['error', '1tbs', { allowSingleLine: true }],
35+
'comma-spacing': ['error', { before: false, after: true }],
36+
'no-lonely-if': 'error',
37+
'dot-notation': 'error',
38+
'no-else-return': 'error',
39+
'no-tabs': 'error',
40+
'no-trailing-spaces': [
41+
'error',
42+
{
43+
skipBlankLines: false,
44+
ignoreComments: false,
45+
},
46+
],
47+
'no-var': 'error',
48+
'unicode-bom': ['error', 'never'],
49+
curly: ['error', 'all'],
50+
'object-curly-spacing': ['error', 'always'],
51+
'keyword-spacing': ['error'],
52+
'require-atomic-updates': 0,
53+
'linebreak-style': ['error', 'unix'],
54+
'unicorn/prefer-node-protocol': ['error'],
55+
'import/extensions': ['error', 'ignorePackages'],
56+
'no-restricted-syntax': [
57+
'error',
58+
'IfStatement > ExpressionStatement > AssignmentExpression',
59+
],
60+
'unicorn/prefer-ternary': 'error',
61+
},
62+
overrides: [
63+
{
64+
files: ['*.ts'],
65+
rules: {
66+
// see https://stackoverflow.com/questions/55280555/typescript-eslint-eslint-plugin-error-route-is-defined-but-never-used-no-un
67+
'no-unused-vars': 'off',
68+
'@typescript-eslint/no-unused-vars': 'error',
69+
'@typescript-eslint/consistent-type-imports': 'error',
70+
'no-undef': 'off',
71+
// allow overloads
72+
'no-redeclare': 'off',
73+
},
74+
},
75+
{
76+
files: ['*.test.ts'],
77+
rules: {
78+
'dot-notation': 'off',
79+
},
80+
},
81+
],
82+
}
83+
84+
module.exports = config

.github/workflows/ci.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches:
7+
- main
8+
- v8
9+
10+
permissions:
11+
contents: read
12+
13+
jobs:
14+
lint:
15+
name: Lint
16+
runs-on: ubuntu-latest
17+
steps:
18+
- name: Checkout
19+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
20+
21+
- name: Setup Node
22+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
23+
with:
24+
node-version: 22
25+
cache: 'npm'
26+
27+
- name: Install
28+
run: npm ci
29+
30+
- name: Lint
31+
run: npm run lint
32+
33+
build-test:
34+
name: Build & test (node ${{ matrix.node-version }})
35+
runs-on: ubuntu-latest
36+
strategy:
37+
fail-fast: false
38+
matrix:
39+
node-version: ['18.20', '20', '22']
40+
steps:
41+
- name: Checkout
42+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
43+
44+
- name: Setup Node
45+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
46+
with:
47+
node-version: ${{ matrix.node-version }}
48+
cache: 'npm'
49+
50+
- name: Install
51+
run: npm ci
52+
53+
- name: Build
54+
run: npm run build
55+
56+
- name: Test
57+
run: npm test

.github/workflows/release.yml

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
name: Release
2+
3+
# Publishes @wdio/browserstack-service to npm via OIDC Trusted Publishing
4+
# (no long-lived NPM_TOKEN). One-time setup by an @wdio npm org admin on npmjs.com:
5+
# @wdio/browserstack-service -> Settings -> Trusted Publisher -> GitHub Actions
6+
# Organization/user: browserstack
7+
# Repository: wdio-browserstack-service
8+
# Workflow filename: release.yml
9+
# Environment: (leave empty)
10+
# Requires: PUBLIC repo (for provenance), npm >= 11.5.1, Node >= 22.14.0.
11+
#
12+
# The gRPC/protobuf client is generated inline at build time (buf generate); there is no
13+
# separate core package for this workflow to version or publish.
14+
#
15+
# Release model (publishing is MANUAL):
16+
# * push to main / v8 -> opens/updates the "Version Packages" PR only. NEVER publishes;
17+
# merging that PR does NOT publish either.
18+
# * Run workflow (publish) -> publishes the merged version to npm (main -> `latest`,
19+
# v8 -> `v8`) with git tag + GitHub release + provenance.
20+
# * Run workflow (canary) -> snapshot prerelease to the npm `canary` dist-tag.
21+
22+
on:
23+
push:
24+
branches:
25+
- main # v9 line -> opens Version PR (publish target: dist-tag "latest")
26+
- v8 # v8 line -> opens Version PR (publish target: dist-tag "v8" via publishConfig.tag)
27+
workflow_dispatch:
28+
inputs:
29+
publish:
30+
description: 'Publish the merged version to npm (main -> `latest`, v8 -> `v8`). Merge the "Version Packages" PR first so there are no pending changesets.'
31+
type: boolean
32+
default: false
33+
canary:
34+
description: 'Publish a canary prerelease to the npm `canary` dist-tag (validates OIDC + provenance end-to-end; never touches `latest`). Requires at least one pending changeset.'
35+
type: boolean
36+
default: false
37+
38+
# Never run main and v8 releases on top of each other.
39+
concurrency: release-${{ github.ref }}
40+
41+
permissions:
42+
contents: write # commit the "Version Packages" PR + create git tags
43+
pull-requests: write # open the "Version Packages" PR
44+
id-token: write # OIDC for npm trusted publishing + provenance
45+
46+
jobs:
47+
release:
48+
name: Release
49+
runs-on: ubuntu-latest
50+
steps:
51+
- name: Checkout
52+
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4
53+
with:
54+
fetch-depth: 0 # Changesets needs full history/tags
55+
56+
- name: Setup Node
57+
# NOTE: intentionally NO `registry-url:` here. setup-node's registry-url writes
58+
# `//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}` into ~/.npmrc; with no
59+
# NODE_AUTH_TOKEN that becomes an empty token line that can shadow OIDC Trusted
60+
# Publishing at `npm publish` time. npm already defaults to registry.npmjs.org and
61+
# publishConfig.access=public handles the scoped publish, so the line isn't needed.
62+
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4
63+
with:
64+
node-version: 22 # resolves to >= 22.14 on the runner (OIDC floor)
65+
cache: 'npm'
66+
67+
# Trusted Publishing needs npm >= 11.5.1. Pin to the 11.x line so a future
68+
# npm major can never silently change publish behaviour.
69+
- name: Upgrade npm to an OIDC-capable version
70+
run: npm install -g npm@11
71+
72+
- name: Install
73+
run: npm ci
74+
75+
- name: Build
76+
run: npm run build
77+
78+
- name: Test
79+
run: npm test
80+
81+
# Version PR (push to main / v8): run changesets in VERSION-ONLY mode — open or update the
82+
# "Version Packages" PR (version bump + CHANGELOG). This step NEVER publishes: with no
83+
# `publish:` input, once the Version PR is merged (a push with no pending changesets) the
84+
# action simply no-ops. Publishing is the separate, manual step below.
85+
- name: Open/update the "Version Packages" PR
86+
if: github.event_name == 'push'
87+
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1
88+
with:
89+
version: npm run version # changeset version — manages the Version PR only
90+
createGithubReleases: false
91+
env:
92+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
93+
94+
# Publish (manual, workflow_dispatch with publish=true): publish the already-versioned
95+
# package to npm — main -> `latest`, v8 -> `v8` (via publishConfig.tag) — with git tag,
96+
# GitHub release, and provenance, over the OIDC trusted publisher (no NPM_TOKEN).
97+
# Merge the "Version Packages" PR first: this publishes only when there are no pending
98+
# changesets. If any remain, the action safely opens/updates the Version PR instead.
99+
- name: Publish to npm
100+
if: github.event_name == 'workflow_dispatch' && inputs.publish
101+
uses: changesets/action@a45c4d594aa4e2c509dc14a9f2b3b67ba3780d0d # v1
102+
with:
103+
publish: npm run release # changeset publish (honors publishConfig.tag per branch)
104+
createGithubReleases: true
105+
env:
106+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
107+
# No NPM_TOKEN: auth is OIDC via id-token: write above.
108+
NPM_CONFIG_PROVENANCE: 'true'
109+
110+
# Canary (manual, workflow_dispatch with canary=true): snapshot-version the pending
111+
# changesets and publish a prerelease to the `canary` dist-tag via the SAME OIDC trusted
112+
# publisher. Validates OIDC + provenance end-to-end without touching `latest`.
113+
# snapshot.useCalculatedVersion=true in .changeset/config.json makes the version
114+
# <next>-canary-<datetime> (e.g. 9.30.0-canary-...). Requires >=1 pending changeset.
115+
- name: Canary publish to `canary` dist-tag
116+
if: github.event_name == 'workflow_dispatch' && inputs.canary
117+
run: |
118+
npx changeset version --snapshot canary
119+
npx changeset publish --no-git-tag --tag canary
120+
env:
121+
NPM_CONFIG_PROVENANCE: 'true'

.gitignore

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,24 @@
11
node_modules
2+
3+
# build outputs
24
dist
35
generated
6+
build
7+
src/generated
8+
packages/*/dist
9+
packages/*/build
10+
packages/*/src/generated
11+
12+
# test/coverage
13+
coverage
14+
packages/*/coverage
15+
16+
# packed tarballs & logs
17+
*.tgz
18+
*.log
19+
logs
20+
21+
# local/editor
22+
.DS_Store
23+
.env
24+
.env.*

0 commit comments

Comments
 (0)