Skip to content

Add SDK regression GHA workflow#136

Open
agrawal-ayush wants to merge 1 commit intomasterfrom
feat/sdk-regression-gha-workflow
Open

Add SDK regression GHA workflow#136
agrawal-ayush wants to merge 1 commit intomasterfrom
feat/sdk-regression-gha-workflow

Conversation

@agrawal-ayush
Copy link
Copy Markdown
Collaborator

Summary

  • Adds sdk-regression.yml workflow triggered via workflow_dispatch
  • Accepts inputs: Maven profile, BrowserStack credentials, optional JAR/binary URLs
  • Runs mvn test -P {profile}, extracts o11y_build_uuid from agent logs
  • Uploads results.json artifact with build IDs for external assertion runners
  • Supports pre-built JAR URL (skips Maven Central LATEST) for branch testing

Context

Part of effort to offload SDK Java regression test execution from Jenkins to GitHub Actions. This workflow handles the sample repo test execution; assertions run externally (Jenkins or local).

Test plan

  • Trigger workflow manually via gh workflow run with real BS credentials
  • Verify results.json artifact contains valid o11y_build_uuid
  • Verify Maven test executes against BrowserStack (sessions visible in dashboard)
  • Test with jar_url input to validate custom JAR flow

🤖 Generated with Claude Code

Adds a workflow_dispatch triggered workflow that runs TestNG sample tests
with configurable Maven profile, BrowserStack credentials, and optional
pre-built JAR/binary URLs. Outputs build IDs as downloadable artifacts
for external assertion runners.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@agrawal-ayush agrawal-ayush requested a review from a team as a code owner April 16, 2026 13:07
Comment on lines +37 to +206
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: ${{ inputs.java_version }}
cache: 'maven'

- name: Download SDK JAR (if jar_url provided)
if: inputs.jar_url != ''
run: |
echo "Downloading SDK JAR from: ${{ inputs.jar_url }}"
JAR_URL="${{ inputs.jar_url }}"
# Add https:// if not present
if [[ ! "$JAR_URL" =~ ^https?:// ]]; then
JAR_URL="https://$JAR_URL"
fi
curl -fSL "$JAR_URL" -o /tmp/browserstack-java-sdk.jar
echo "JAR_PATH=/tmp/browserstack-java-sdk.jar" >> $GITHUB_ENV

- name: Update pom.xml for custom JAR
if: inputs.jar_url != ''
run: |
# Replace the SDK dependency to use system scope with local JAR
python3 - <<'PYEOF'
import xml.etree.ElementTree as ET

ET.register_namespace('', 'http://maven.apache.org/POM/4.0.0')
tree = ET.parse('pom.xml')
root = tree.getroot()
ns = {'m': 'http://maven.apache.org/POM/4.0.0'}

for dep in root.findall('.//m:dependency', ns):
artifact = dep.find('m:artifactId', ns)
if artifact is not None and artifact.text == 'browserstack-java-sdk':
scope = dep.find('m:scope', ns)
if scope is None:
scope = ET.SubElement(dep, 'scope')
scope.text = 'system'

version = dep.find('m:version', ns)
if version is not None:
version.text = '1.0'

sys_path = dep.find('m:systemPath', ns)
if sys_path is None:
sys_path = ET.SubElement(dep, 'systemPath')
sys_path.text = '/tmp/browserstack-java-sdk.jar'

tree.write('pom.xml', xml_declaration=True, encoding='UTF-8')
PYEOF
echo "Updated pom.xml for custom JAR"
cat pom.xml

- name: Download binary (if bin_url provided)
if: inputs.bin_url != ''
run: |
BIN_URL="${{ inputs.bin_url }}"
if [[ ! "$BIN_URL" =~ ^https?:// ]]; then
BIN_URL="https://$BIN_URL"
fi
curl -fSL "$BIN_URL" -o /tmp/binary.zip
cd /tmp && unzip -o binary.zip
BIN_FILE=$(ls /tmp/BrowserStackLocal* 2>/dev/null | head -1)
if [ -n "$BIN_FILE" ]; then
chmod +x "$BIN_FILE"
echo "SDK_CLI_BIN_PATH=$BIN_FILE" >> $GITHUB_ENV
fi

- name: Write browserstack.yml
run: |
cat > browserstack.yml <<'YML'
userName: ${{ inputs.bs_username }}
accessKey: ${{ inputs.bs_accesskey }}
projectName: ${{ inputs.project_name }}
buildName: ${{ inputs.build_name }}
buildIdentifier: '#${BUILD_NUMBER}'
framework: testng
platforms:
- os: Windows
osVersion: 10
browserName: Chrome
browserVersion: latest
parallelsPerPlatform: 1
browserstackLocal: true
debug: true
networkLogs: true
testObservability: true
source: testng:sample-master:v1.1
YML

- name: Run Maven test
id: mvn-test
run: |
export BROWSERSTACK_USERNAME="${{ inputs.bs_username }}"
export BROWSERSTACK_ACCESS_KEY="${{ inputs.bs_accesskey }}"
export BROWSERSTACK_BUILD_NAME="${{ inputs.build_name }}"
export BROWSERSTACK_PROJECT_NAME="${{ inputs.project_name }}"
if [ -n "$SDK_CLI_BIN_PATH" ]; then
export SDK_CLI_BIN_PATH="$SDK_CLI_BIN_PATH"
fi

mvn test -P ${{ inputs.profile }} --batch-mode 2>&1 | tee /tmp/mvn-output.log
MVN_EXIT=${PIPESTATUS[0]}
echo "mvn_exit=$MVN_EXIT" >> $GITHUB_OUTPUT

# Even if mvn returns non-zero (test failures), we still want to extract build IDs
# Only fail if mvn couldn't run at all
if [ $MVN_EXIT -ne 0 ]; then
echo "::warning::Maven exited with code $MVN_EXIT"
fi

- name: Extract build IDs from logs
id: extract
if: always()
run: |
# Extract o11y_build_uuid from javaagent log
O11Y_UUID=""
if [ -f "log/browserstack-javaagent.log" ]; then
O11Y_UUID=$(grep 'automation\.browserstack\.com' log/browserstack-javaagent.log | tail -1 | grep -oP 'builds/\K[a-z0-9]+' || true)
fi
# Fallback: check mvn output
if [ -z "$O11Y_UUID" ]; then
O11Y_UUID=$(grep 'observability.browserstack.com/builds/' /tmp/mvn-output.log | tail -1 | grep -oP 'builds/\K[a-z0-9]+' || true)
fi
echo "o11y_build_uuid=$O11Y_UUID" >> $GITHUB_OUTPUT
echo "Extracted o11y_build_uuid: $O11Y_UUID"

- name: Build results JSON
if: always()
run: |
python3 - <<PYEOF
import json, os

results = {
"build_name": "${{ inputs.build_name }}",
"project_name": "${{ inputs.project_name }}",
"profile": "${{ inputs.profile }}",
"o11y_build_uuid": "${{ steps.extract.outputs.o11y_build_uuid }}",
"mvn_exit_code": int("${{ steps.mvn-test.outputs.mvn_exit || '1' }}"),
"java_version": "${{ inputs.java_version }}",
}

os.makedirs("/tmp/results", exist_ok=True)
with open("/tmp/results/results.json", "w") as f:
json.dump(results, f, indent=2)

print(json.dumps(results, indent=2))
PYEOF

- name: Upload results artifact
if: always()
uses: actions/upload-artifact@v4
with:
name: sdk-regression-results
path: /tmp/results/results.json
retention-days: 7

- name: Upload logs
if: always()
uses: actions/upload-artifact@v4
with:
name: sdk-regression-logs
path: |
log/
/tmp/mvn-output.log
retention-days: 7
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.

2 participants