Open
Conversation
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>
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
sdk-regression.ymlworkflow triggered viaworkflow_dispatchmvn test -P {profile}, extractso11y_build_uuidfrom agent logsresults.jsonartifact with build IDs for external assertion runnersContext
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
gh workflow runwith real BS credentialsresults.jsonartifact contains valido11y_build_uuidjar_urlinput to validate custom JAR flow🤖 Generated with Claude Code