Skip to content
Latchkey

Browserstack workflow (jquery/jquery)

The Browserstack workflow from jquery/jquery, explained and optimized by Latchkey.

A

CI health: A - excellent

Point runs-on at Latchkey and get run de-duplication, self-healing for flaky steps, and up to 58% lower cost, applied automatically.

Grade your own workflow free or run it on Latchkey →
Source: jquery/jquery.github/workflows/browserstack.ymlLicense MITView source

What it does

This is the Browserstack workflow from the jquery/jquery repository, a real project running GitHub Actions. It is shown here with attribution under its MIT license.

Below, Latchkey shows a faster, safer version produced by its optimization engine.

The workflow

workflow (.yml)
name: Browserstack

on:
  push:
    branches:
      - main

permissions:
  contents: read # to fetch code (actions/checkout)

jobs:
  test:
    runs-on: ubuntu-latest
    environment: browserstack
    env:
      BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
      BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
      NODE_VERSION: 24.x
    name: ${{ matrix.BROWSER }}
    concurrency:
      group: ${{ github.workflow }}-${{ matrix.BROWSER }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        BROWSER:
          - 'IE_11'
          # BrowserStack makes Safari on beta macOS versions available without marking
          # either the OS or the browser as beta, so we have no way to resolve "latest"
          # to the lastest stable version. Given that major Safari version updates
          # only come once a year, we'll just keep updating them each year, together
          # with related iOS versions.
          - 'Safari_26'
          - 'Safari_18'
          - 'Chrome_latest'
          - 'Chrome_latest-1'
          - 'Opera_latest'
          - 'Edge_latest'
          - 'Edge_latest-1'
          - 'Firefox_latest'
          - 'Firefox_latest-1'
          - '_:iPhone 17_iOS_26'
          - '_:iPhone 16_iOS_18'
          - '_:iPhone 15 Pro_iOS_17'
          - '_:iPad Air 13 2025_iOS_26'
          - '_:iPad Air 13 2025_iOS_18'
    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0

      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: npm
          cache-dependency-path: '**/package-lock.json'

      - name: Install dependencies
        run: npm ci

      - name: Build jQuery
        run: npm run build:all

      - name: Pretest script
        run: npm run pretest

      - name: Run tests
        run: |
          npm run test:unit -- -v -c jtr-isolate.yml \
            --browserstack "${{ matrix.BROWSER }}" \
            --run-id ${{ github.run_id }}

The same workflow, on Latchkey

Removes redundant runs and caps runaway jobs. Added and changed lines are highlighted.

name: Browserstack
 
on:
  push:
    branches:
      - main
 
permissions:
  contents: read # to fetch code (actions/checkout)
 
concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true
 
jobs:
  test:
    runs-on: latchkey-small
    environment: browserstack
    env:
      BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
      BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
      NODE_VERSION: 24.x
    name: ${{ matrix.BROWSER }}
    concurrency:
      group: ${{ github.workflow }}-${{ matrix.BROWSER }}
    timeout-minutes: 30
    strategy:
      fail-fast: false
      matrix:
        BROWSER:
          - 'IE_11'
          # BrowserStack makes Safari on beta macOS versions available without marking
          # either the OS or the browser as beta, so we have no way to resolve "latest"
          # to the lastest stable version. Given that major Safari version updates
          # only come once a year, we'll just keep updating them each year, together
          # with related iOS versions.
          - 'Safari_26'
          - 'Safari_18'
          - 'Chrome_latest'
          - 'Chrome_latest-1'
          - 'Opera_latest'
          - 'Edge_latest'
          - 'Edge_latest-1'
          - 'Firefox_latest'
          - 'Firefox_latest-1'
          - '_:iPhone 17_iOS_26'
          - '_:iPhone 16_iOS_18'
          - '_:iPhone 15 Pro_iOS_17'
          - '_:iPad Air 13 2025_iOS_26'
          - '_:iPad Air 13 2025_iOS_18'
    steps:
      - name: Checkout
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
 
      - name: Use Node.js ${{ env.NODE_VERSION }}
        uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
        with:
          node-version: ${{ env.NODE_VERSION }}
          cache: npm
          cache-dependency-path: '**/package-lock.json'
 
      - name: Install dependencies
        run: npm ci
 
      - name: Build jQuery
        run: npm run build:all
 
      - name: Pretest script
        run: npm run pretest
 
      - name: Run tests
        run: |
          npm run test:unit -- -v -c jtr-isolate.yml \
            --browserstack "${{ matrix.BROWSER }}" \
            --run-id ${{ github.run_id }}
 

What changed

What Latchkey heals here

This workflow has steps that commonly fail on transient issues (network, registries, flaky browsers). On Latchkey managed runners they are detected, retried, and self-healed instead of failing your build:

This workflow runs 1 job (15 with the matrix expanded) per trigger. On Latchkey the same minutes cost up to 58% less than GitHub-hosted, with zero queue time.

Actions used in this workflow