Skip to content

ci: migrate pipeline to Twilio locked-down agents (Chromium CI image)#850

Open
AnkitSegment wants to merge 8 commits into
masterfrom
buildkite-migrations
Open

ci: migrate pipeline to Twilio locked-down agents (Chromium CI image)#850
AnkitSegment wants to merge 8 commits into
masterfrom
buildkite-migrations

Conversation

@AnkitSegment

Copy link
Copy Markdown
Contributor

Summary

Fixes the Buildkite pipeline on the Twilio locked-down general-039 agents. The previous pipeline still depended on Segment-only infrastructure and failed every run.

Verified green on build #11 (Build and Test + SauceLabs both passed).

Root causes fixed

  • Segment cache-buildkite-pluginshasum: command not found + S3 403 on the locked-down agents. Removed.
  • No browser in the test image — tests run Karma ChromeHeadless, but node:*-alpine ships no browser. Added a CI image with Chromium.
  • No public internet egressdocker.io pulls TLS-timeout, so apk add chromium can't reach the public Alpine CDN. Chromium is installed from the Twilio base-alpine apk mirror.
  • phantomjs-prebuilt postinstall download (the real blocker) — several integrations pull it as a devDependency; its install downloads a binary from a public CDN and fails yarn install. It has no skip flag, so a tiny phantomjs stub on PATH reporting 2.1.1 makes its installer skip the download. The phantom launcher is unused — tests only run ChromeHeadless.
  • SauceLabs used an unauthenticated Segment ECR image; moved to the same compose CI image.

Changes

File Change
.buildkite/Dockerfile.ci CI image: node (Twilio ECR mirror) + Chromium (Twilio base-alpine apk mirror) + phantomjs stub
docker-compose-ci.yml Compose service that builds the CI image and runs the suite
.buildkite/pipeline.yml Build/Test + SauceLabs steps via the docker-compose plugin with mount-checkout
karma.conf.js ChromeHeadlessNoSandbox launcher (container runs as root)
.npmrc Twilio Artifactory virtual-npm registry

Notes / follow-ups

  • On a branch with no integration changes, yarn test runs --since master and reports "no packages" — passes without exercising integration tests. The CI infra is verified working; a branch touching an integration will exercise real Chrome runs.
  • The Upload Assets steps still call ./.buildkite/upload.sh / publish.sh, which rely on Segment agent hooks (SEGMENT_LIB_PATH, run-with-role). Being verified separately on staging.

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings June 18, 2026 06:03

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The upload/publish steps are moved onto general-039 but still depend on Segment agent hooks (SEGMENT_LIB_PATH/run-with-role), which will likely break master/staging pipelines.

Pull request overview

Migrates the Buildkite CI pipeline to run on Twilio locked-down general-039 agents by introducing a custom Chromium-capable CI image, switching steps to the docker-compose plugin, and pointing npm/yarn at Twilio’s Artifactory registry to avoid Segment-only infrastructure dependencies.

Changes:

  • Add a custom CI Docker image (.buildkite/Dockerfile.ci) that installs Chromium (via Twilio’s Alpine mirror) and provides a phantomjs stub to bypass phantomjs-prebuilt downloads in no-egress environments.
  • Introduce a CI-only compose file (docker-compose-ci.yml) and update Buildkite pipeline steps to run test/SauceLabs jobs via the docker-compose plugin on general-039.
  • Update Karma to use a ChromeHeadlessNoSandbox launcher and add an .npmrc pointing to Twilio’s virtual npm registry.
File summaries
File Description
karma.conf.js Switches default launcher to ChromeHeadlessNoSandbox and defines the custom launcher/flags.
docker-compose-ci.yml Adds a CI-only compose definition to build/run the new Chromium test image and propagate needed env vars.
.npmrc Sets npm registry to Twilio Artifactory virtual registry.
.buildkite/pipeline.yml Migrates steps to general-039 and uses the docker-compose plugin for build/test and SauceLabs jobs.
.buildkite/Dockerfile.ci Adds a locked-down CI image (Node + Chromium + build toolchain + phantomjs stub) suitable for no-egress agents.

Copilot's findings

  • Files reviewed: 5/6 changed files
  • Comments generated: 3

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread karma.conf.js
Comment on lines +18 to +28
// Run headless Chrome with --no-sandbox: the CI container runs as root,
// where Chrome's sandbox refuses to start. CHROME_BIN points at the
// Chromium installed in .buildkite/Dockerfile.ci.
browsers: ['ChromeHeadlessNoSandbox'],

customLaunchers: {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
flags: ['--no-sandbox', '--disable-gpu', '--disable-dev-shm-usage']
}
},
Comment thread .buildkite/pipeline.yml
branches: master staging
agents:
queue: v1
queue: general-039
Comment thread .buildkite/pipeline.yml
branches: master
agents:
queue: v1
queue: general-039
Copilot AI review requested due to automatic review settings June 18, 2026 08:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The repo-wide .npmrc registry override can break non-Twilio/local workflows and the pipeline’s auth-token setting should be safely quoted to avoid shell parsing issues.

Copilot's findings
  • Files reviewed: 7/8 changed files
  • Comments generated: 5

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .buildkite/pipeline.yml
queue: general-039
command:
- npm config set "//registry.npmjs.org/:_authToken" $${NPM_TOKEN}
- npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" $${NPM_TOKEN}
Comment thread .buildkite/pipeline.yml
queue: general-039
command:
- npm config set "//registry.npmjs.org/:_authToken" $${NPM_TOKEN}
- npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" $${NPM_TOKEN}
Comment thread .buildkite/pipeline.yml Outdated
queue: general-039
command:
- npm config set "//registry.npmjs.org/:_authToken" $${NPM_TOKEN}
- npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" $${NPM_TOKEN}
Comment thread .buildkite/pipeline.yml Outdated
queue: general-039
command:
- npm config set "//registry.npmjs.org/:_authToken" $${NPM_TOKEN}
- npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" $${NPM_TOKEN}
Comment thread .npmrc Outdated
@@ -0,0 +1 @@
registry=https://npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/
Copilot AI review requested due to automatic review settings June 18, 2026 20:41
@sayan-das-in sayan-das-in force-pushed the buildkite-migrations branch from a0e576d to 653a916 Compare June 18, 2026 20:41
@sayan-das-in sayan-das-in force-pushed the buildkite-migrations branch from 653a916 to 87cba5a Compare June 18, 2026 20:47

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

CI will fail as submitted due to missing yarn.lock updates for new dependencies and inconsistent Docker Compose service naming between docker-compose-ci.yml, Buildkite config, and scripts.

Copilot's findings

Comments suppressed due to low confidence (1)

.buildkite/pipeline.yml:46

  • The stated goal is migrating off Segment-only Buildkite infrastructure for locked-down agents, but this pipeline still includes segmentio/cache-buildkite-plugin in the SauceLabs and asset upload steps and still runs SauceLabs inside the Segment ECR image (528451384384.dkr.ecr.../analytics.js-integrations-ci). Those dependencies are called out in the PR description as failing on locked-down agents (S3 403 / missing tooling), so those steps are likely to remain broken unless they’re also migrated/removed.
  - label: "SauceLabs"
    key: "sauce_labs"
    branches: "!master"
    soft_fail: true
    command:
      - npm config set "//registry.npmjs.org/:_authToken" $${NPM_TOKEN}
      - yarn install --ignore-engines
      - yarn test:ci
    plugins:
      - ssh://git@github.com/segmentio/cache-buildkite-plugin#v1.0.0:
          key: "v1-cache-dev-{{ checksum 'yarn.lock' }}"
          paths: ["node_modules/"]
          s3_bucket_name: "segment-buildkite-cache"
      - docker#v3.3.0:
          image: 528451384384.dkr.ecr.us-west-2.amazonaws.com/analytics.js-integrations-ci
          user: root
          environment:
  • Files reviewed: 163/164 changed files
  • Comments generated: 4

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread package.json
"eslint-plugin-prettier": "^3.1.4",
"fs-extra": "^9.0.1",
"husky": "^4.3.8",
"karma-webdriver-launcher": "^1.0.8",
Comment thread docker-compose-ci.yml Outdated
Comment on lines +10 to +12
test:
image: 018537234677.dkr.ecr.us-east-1.amazonaws.com/docker.io/library/node:22.18.0-bookworm
working_dir: /app
Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +11 to +14
- docker-compose#v5.12.1:
run: e2e-runner
config: docker-compose-ci.yml
mount-buildkite-agent: true
Comment thread karma.conf.js Outdated
Comment on lines 18 to 31
customLaunchers: {
ChromeRemote: {
base: 'WebDriver',
config: {
hostname: process.env.SELENIUM_HOST || 'localhost',
port: 4444
},
browserName: 'chrome',
pseudoActivityInterval: 30000
}
},

browsers: ['ChromeRemote'],

Copilot AI review requested due to automatic review settings June 18, 2026 20:58
@sayan-das-in sayan-das-in force-pushed the buildkite-migrations branch from 87cba5a to b7bac2f Compare June 18, 2026 20:58

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

There are CI-breaking configuration mismatches (non-existent compose service names) and multiple verified discrepancies with the PR description (missing CI Dockerfile/.npmrc and remaining incompatible cache plugin usage).

Copilot's findings
  • Files reviewed: 163/164 changed files
  • Comments generated: 11

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +25 to +28
- docker-compose#v5.12.1:
run: e2e-runner
config: docker-compose-ci.yml
mount-buildkite-agent: true
Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +11 to +14
- docker-compose#v5.12.1:
run: test
config: docker-compose-ci.yml
mount-buildkite-agent: true
Comment thread .buildkite/pipeline.yml
Comment on lines 75 to 79
- label: ":cloud: Upload Assets to stage bucket"
branches: master staging
agents:
queue: v1
command:
- echo "--- Upload"
- NODE_ENV=production ./.buildkite/upload.sh
Comment thread .buildkite/pipeline.yml
Comment on lines 86 to 90
- label: ":cloud: Upload Assets to production bucket"
branches: master
agents:
queue: v1
command:
- echo "--- Upload"
- NODE_ENV=production ./.buildkite/publish.sh
Comment thread .buildkite/upload.sh
--volume "$PWD:/workdir" --workdir /workdir \
-e NPM_TOKEN -e NODE_ENV \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
app sh -e -c '
Comment thread karma.conf.js Outdated
}
},

browsers: ['ChromeRemote'],
Comment thread .buildkite/pipeline.yml Outdated
Comment on lines 4 to 6
env:
COMPOSE_PROFILES: "ci"
branches: "!master"
Comment thread docker-compose-ci.yml Outdated
Comment on lines +10 to +12
test:
image: 018537234677.dkr.ecr.us-east-1.amazonaws.com/docker.io/library/node:22.18.0-bookworm
working_dir: /app
Comment thread .buildkite/upload.sh
-e NPM_TOKEN -e NODE_ENV \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
app sh -e -c '
npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" "${NPM_TOKEN}"
Comment thread .buildkite/publish.sh
-e NPM_TOKEN -e NODE_ENV \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
app sh -e -c '
npm config set "//npmjs.artifacts.twilio.com/artifactory/api/npm/virtual-npm-twilio/:_authToken" "${NPM_TOKEN}"
AnkitSegment and others added 2 commits June 19, 2026 13:52
These dependencies were unused — no karma config ever sets PhantomJS as
a browser (all use ChromeRemote/SauceLabs). The phantomjs-prebuilt post-install
script downloads a binary from GitHub which times out in CI, breaking builds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add healthcheck to chrome service so test container waits until
  Selenium Grid is ready before starting (fixes race condition)
- Fix karma.conf.js ChromeRemote config to use `url` instead of
  hostname/port — karma-webdriver-launcher requires a `url` key,
  the old config caused Selenium to receive "url" as a session ID

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 19, 2026 08:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The Buildkite pipeline and upload/publish scripts reference docker-compose services that don’t exist in docker-compose-ci.yml, which will break CI execution.

Copilot's findings
  • Files reviewed: 164/165 changed files
  • Comments generated: 6

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +24 to +28
plugins:
- ssh://git@github.com/segmentio/cache-buildkite-plugin#v1.0.0:
key: "v1-cache-dev-{{ checksum 'yarn.lock' }}"
paths: [ "node_modules/" ]
s3_bucket_name: "segment-buildkite-cache"
save: true
- docker#v3.3.0:
image: circleci/node:12.18-browsers
user: root
environment:
- NPM_TOKEN
- CHROME-BIN=google-chrome
- docker-compose#v5.12.1:
run: e2e-runner
config: docker-compose-ci.yml
mount-buildkite-agent: true
Comment thread .buildkite/pipeline.yml
queue: v1
command:
- echo "--- Upload"
- NODE_ENV=production ./.buildkite/upload.sh
Comment thread .buildkite/upload.sh
Comment on lines +29 to +33
docker compose -f docker-compose-ci.yml run --rm \
--volume "$PWD:/workdir" --workdir /workdir \
-e NPM_TOKEN -e NODE_ENV \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
app sh -e -c '
Comment thread .buildkite/publish.sh
Comment on lines +29 to +33
docker compose -f docker-compose-ci.yml run --rm \
--volume "$PWD:/workdir" --workdir /workdir \
-e NPM_TOKEN -e NODE_ENV \
-e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -e AWS_SESSION_TOKEN \
app sh -e -c '
Comment thread karma.conf.js Outdated
Comment on lines +18 to +22
customLaunchers: {
ChromeRemote: {
base: 'WebDriver',
config: {
url: 'http://' + (process.env.SELENIUM_HOST || 'localhost') + ':4444/wd/hub'
Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +11 to +14
- docker-compose#v5.12.1:
run: test
config: docker-compose-ci.yml
mount-buildkite-agent: true
AnkitSegment and others added 2 commits June 19, 2026 14:40
The docker-compose plugin runs 'docker compose run' and only passes env
vars explicitly listed under its environment key — the compose file's
environment block is not automatically forwarded. Add SELENIUM_HOST=chrome
explicitly so karma-webdriver-launcher connects to the chrome service
instead of falling back to localhost:4444 (ECONNREFUSED).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The b7bac2f migration replaced the working Chromium-in-container setup
(from 4e9fe51) with a Selenium standalone-chrome:126 + karma-webdriver-launcher
approach that cannot work: wd@1.14.0 speaks JSON Wire Protocol but
Selenium 4 only speaks W3C WebDriver, causing every session to get
session ID "url" and fail with NoSuchSessionException.

Restore 4e9fe51's approach:
- .buildkite/Dockerfile.ci: build image with node + Chromium from Twilio
  ECR/apk mirrors (no public egress needed)
- docker-compose-ci.yml: single 'app' service built from Dockerfile.ci
- karma.conf.js: ChromeHeadlessNoSandbox (no Selenium, no WebDriver)
- .buildkite/pipeline.yml: docker-compose plugin with mount-checkout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 19, 2026 09:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The repo’s Karma config runs ChromeHeadless but karma-chrome-launcher has been removed from dependencies (package.json/yarn.lock), so test execution will fail until the Chrome launcher dependency is restored.

Copilot's findings
  • Files reviewed: 165/166 changed files
  • Comments generated: 4

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread package.json
"eslint-plugin-prettier": "^3.1.4",
"fs-extra": "^9.0.1",
"husky": "^4.3.8",
"karma-webdriver-launcher": "^1.0.8",
"karma": "^4.1.0",
"karma-browserify": "^6.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-webdriver-launcher": "^1.0.8",
Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +41 to +42
- wait: ~
depends_on: ["build_master", "sauce_labs_master"]
depends_on: ["build_master"]
Comment thread .buildkite/Dockerfile.ci
Comment on lines +38 to +47
# Several integrations still list phantomjs-prebuilt as a devDependency. Its
# postinstall downloads a binary from a public CDN, which is unreachable on the
# no-egress agents and fails `yarn install`. phantomjs-prebuilt has no
# skip-download flag, but its installer (tryPhantomjsOnPath) skips the download
# when a `phantomjs` already on PATH reports the expected version (2.1.1). The
# tests only ever launch ChromeHeadless (karma.conf.js) -- the phantom launcher
# is an unused devDependency -- so a stub that just answers `--version` is
# enough to satisfy the installer without ever running as a browser.
RUN printf '#!/bin/sh\necho 2.1.1\n' > /usr/local/bin/phantomjs && \
chmod +x /usr/local/bin/phantomjs
AnkitSegment and others added 2 commits June 19, 2026 15:14
ChromeHeadlessNoSandbox in karma.conf.js requires karma-chrome-launcher
but it was missing from the workspace root, causing all integrations to
fail with "No provider for launcher:ChromeHeadless".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
b7bac2f replaced karma-chrome-launcher with karma-webdriver-launcher in
boomtrain. Since we now use ChromeHeadlessNoSandbox everywhere, boomtrain
needs karma-chrome-launcher back to launch the browser correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 19, 2026 09:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Not ready to approve

The pipeline changes appear to contradict the PR’s stated SauceLabs migration/verification, and karma-webdriver-launcher is introduced broadly despite being unused by the repo’s Karma configuration.

Copilot's findings
  • Files reviewed: 164/165 changed files
  • Comments generated: 3

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.

Comment thread .buildkite/pipeline.yml Outdated
Comment on lines +41 to +42
- wait: ~
depends_on: ["build_master", "sauce_labs_master"]
depends_on: ["build_master"]
Comment thread package.json
Comment on lines +38 to +39
"karma-chrome-launcher": "^3.1.0",
"karma-webdriver-launcher": "^1.0.8",
Comment on lines 38 to 41
"karma": "^4.1.0",
"karma-browserify": "^6.0.0",
"karma-chrome-launcher": "^2.2.0",
"karma-webdriver-launcher": "^1.0.8",
"karma-mocha": "^1.3.0",
- Restore SauceLabs and SauceLabs Master steps (soft_fail: true)
- Restore wait depends_on both build_master and sauce_labs_master
- Restore cache-buildkite-plugin on Upload Assets steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants