diff --git a/.github/workflows/test-remote-cypress-workflow.yml b/.github/workflows/test-remote-cypress-workflow.yml new file mode 100644 index 000000000..a3e885968 --- /dev/null +++ b/.github/workflows/test-remote-cypress-workflow.yml @@ -0,0 +1,25 @@ +name: Trigger Remote Cypress Workflow + +on: + workflow_dispatch: + inputs: + remote_workflow: + description: 'Trigger Remote Cypress Workflow' + required: false + push: + branches: [ '**' ] + +jobs: + trigger-cypress: + runs-on: ubuntu-latest + env: + REMOTE_GITHUB_PAT: ${{secrets.REMOTE_GITHUB_PAT}} + + steps: + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run Bash Script + run: | + ./remoteCypress.sh + diff --git a/remoteCypress.sh b/remoteCypress.sh new file mode 100755 index 000000000..35881fdba --- /dev/null +++ b/remoteCypress.sh @@ -0,0 +1,184 @@ +#!/bin/bash + +REMOTE_REPO="manasvinibs/OpenSearch-Dashboards" # This is for POC, will be updated to read from manifest file. +WORKFLOW_NAME="remote_cypress_workflow.yml" +API_URL="https://api.github.com/repos/$REMOTE_REPO/actions/workflows/$WORKFLOW_NAME/dispatches" +PAYLOAD="{\"ref\": \"POC\",\"inputs\":{\"build_id\":\"abc2023\"}}" # Build id is the unique id generated for each execution. +GITHUB_TOKEN="$REMOTE_GITHUB_PAT" +UNIQUE_EXECUTION_ID="abc2023" + +function usage() { + echo "" + echo "This script is used to trigger github workflow runners which runs cypress integration tests for plugins installed on a remote OpenSearch/Dashboards cluster outside functional test repository." + echo "--------------------------------------------------------------------------" + echo "Usage: $0 [args]" + echo "" + echo "Required arguments:" + echo "" + echo "Optional arguments:" + echo -e "-b REMOTE_REPO\t, defaults to localhost | 127.0.0.1, can be changed to any IP or domain name for the cluster location." + echo -e "-p CYPRESS_WORKFLOW_NAME\t, defaults to 9200 or 5601 depends on OpenSearch or Dashboards, can be changed to any port for the cluster location." + echo -e "-s SECURITY_ENABLED\t(true | false), defaults to true. Specify the OpenSearch/Dashboards have security enabled or not." + echo -e "-c CREDENTIAL\t(usename:password), no defaults, effective when SECURITY_ENABLED=true." + echo -e "-t TEST_COMPONENTS\t(OpenSearch-Dashboards reportsDashboards etc.), optional, specify test components, separate with space, else test everything." + echo -e "-v VERSION\t, no defaults, indicates the OpenSearch version to test." + echo -e "-o OPTION\t, no defaults, determine the TEST_TYPE value among(default, manifest) in test_finder.sh, optional." + echo -e "-h\tPrint this message." + echo "--------------------------------------------------------------------------" +} + +# Parse command-line arguments +while getopts ":r:w:a:p:t:" opt; do + case $opt in + r) + REMOTE_REPO="$OPTARG" + ;; + w) + WORKFLOW_NAME="$OPTARG" + ;; + a) + API_URL="$OPTARG" + ;; + p) + PAYLOAD="$OPTARG" + ;; + t) + GITHUB_TOKEN="$OPTARG" + ;; + \?) + echo "Invalid option: -$OPTARG" >&2 + exit 1 + ;; + :) + echo "Option -$OPTARG requires an argument." >&2 + exit 1 + ;; + esac +done + + +# Maximum number of retries for triggering remote runner +MAX_RETRIES=3 + +# Trigger the remote github workflow using curl and the PAT token +trigger_remote_workflow() { + curl -L -X POST -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + -w "%{http_code}" \ + "$API_URL" -d "$PAYLOAD" +} +echo "Triggering remote GitHub workflow for Cypress tests in repository: $REMOTE_REPO" + +# Attempt to trigger the remote workflow with retries +for ((i = 1; i <= MAX_RETRIES; i++)); do + echo "Attempting to trigger remote workflow (Attempt $i)" + status_code=$(trigger_remote_workflow) + echo "status_code: $status_code" + + if [[ $status_code -ge 200 && $status_code -lt 300 ]]; then + echo "Remote workflow triggered successfully." + break + else + echo "Failed to trigger remote workflow. Retrying..." + sleep 10 # Adds a delay between retries + fi + + if [ $i -eq $MAX_RETRIES ]; then + echo "Maximum number of retries reached. Exiting." + exit 1 + fi +done + +get_workflow_run_id () { + # Make a GET request to the GitHub API to get the list of workflow runs + workflow_runs=$(curl -s -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/$REMOTE_REPO/actions/workflows/$WORKFLOW_NAME/runs") + echo "Workflow Runs: $workflow_runs" + + # Extract the JSON object whose "name" field contains the string with a unique id of the workflow + matching_workflow=$(echo "$workflow_runs" | jq '.workflow_runs[] | select(.name | contains("abc2023"))') + echo "$matching_workflow" +} + +# Function to check the status of the remote workflow by constantly polling the workflow-run +check_remote_workflow_status() { + local run_id + local status + local conclusion + local run_details + local workflow_runs + local polling_run_id_retries=1 + local polling_workflow_completion_retries=1 + local max_polling_run_id_retries=5 # Keep polling for first 5 minutes to fetch workflow run id till workflow gets generated + local max_polling_workflow_completion_retries=6 # Adjusted for the polling window period. + + matching_workflow_json=$(get_workflow_run_id) + echo "matching_workflow_json: $matching_workflow_json" + + # Check if a matching workflow object was found + while [ -z "$matching_workflow_json" ] && [ $polling_run_id_retries -le $max_polling_run_id_retries ]; do + echo "No matching workflow run object found. Retrying to find Run ID..." + sleep 60 # Wait for 1 minute before retrying + ((polling_run_id_retries++)) + matching_workflow_json=$(get_workflow_run_id) + done + + if [ -n "$matching_workflow_json" ]; then + # Extract the "jobs_url" value from the matching object + jobs_url=$(echo "$matching_workflow_json" | jq -r '.jobs_url') + run_id=$(echo "$matching_workflow_json" | jq -r '.id') + echo "Job URL: $jobs_url" + echo "Run Id: $run_id" + + echo "Checking the workflow run API status, attempt: $polling_workflow_completion_retries" + + # Poll the status until the workflow is completed + while [ $polling_workflow_completion_retries -le $max_polling_workflow_completion_retries ]; do + run_details=$(curl -L -H "Authorization: Bearer $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + "https://api.github.com/repos/$REMOTE_REPO/actions/runs/$run_id") + echo "Response: $run_details" + + # Extract status and conclusion from the run details + status=$(echo "$run_details" | jq -r ".status") + conclusion=$(echo "$run_details" | jq -r ".conclusion") + + # Check if the status indicates that the workflow is complete + if [[ "$status" == "completed" ]]; then + echo "Workflow completed with status: $status" + + # Check if it was successful + if [[ $conclusion == "success" ]]; then + echo "Remote workflow completed successfully." + return 0 # Success + else + echo "Remote workflow completed with errors. Conclusion: $conclusion" + + # Parse the workflow to find any failures in the test + failures=$(echo "$run_details" | jq -r '.jobs[] | select(.conclusion == "failure") | .name') + echo "Test failures: $failures" + + return 1 # Failure + fi + else + echo "Remote workflow is still running. Waiting..." + sleep 600 # Wait for 10 minutes before checking again + ((polling_workflow_completion_retries++)) + fi + done + else + echo "No matching workflow run object found even after retries. Exiting..." + fi + + echo "Remote workflow didn't complete within the specified time." + return 1 # Failure +} + +# Check the status of the remote workflow +check_remote_workflow_status + +exit 0