Skip to content

Commit

Permalink
[POC] Add ability to trigger remote workflow runner outside functiona…
Browse files Browse the repository at this point in the history
…l test repo

Signed-off-by: manasvinibs <[email protected]>
  • Loading branch information
manasvinibs committed Nov 30, 2023
1 parent 76ec82d commit e6deb18
Show file tree
Hide file tree
Showing 2 changed files with 207 additions and 0 deletions.
26 changes: 26 additions & 0 deletions .github/workflows/test-remote-cypress-workflow.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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
name: Remote Cypress Tests
env:
REMOTE_GITHUB_PAT: ${{secrets.REMOTE_GITHUB_PAT}}

steps:
- name: Checkout code
uses: actions/checkout@v2

- name: Run Bash Script
run: |
./remoteCypress.sh
181 changes: 181 additions & 0 deletions remoteCypress.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
#!/bin/bash

# The below params values are taken as an input param
REMOTE_REPO="manasvinibs/OpenSearch-Dashboards" # This is for POC, will be updated to read from manifest file.
WORKFLOW_NAME="remote_cypress_workflow.yml"
GITHUB_TOKEN="$REMOTE_GITHUB_PAT"
UNIQUE_WORKFLOW_ID=$(uuidgen)
echo "Unique Execution ID: $UNIQUE_WORKFLOW_ID"
API_URL="https://api.github.com/repos/$REMOTE_REPO/actions/workflows/$WORKFLOW_NAME/dispatches"
BRANCH_NAME="POC"
PAYLOAD="{\"ref\": \"$BRANCH_NAME\",\"inputs\":{\"build_id\":\"$UNIQUE_WORKFLOW_ID\"}}" # Build id is the unique id generated for each execution.


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 -e "-b REMOTE_REPO\t, "
echo -e "-p GITHUB_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 OS_URL\t, defaults to true. Specify the OpenSearch/Dashboards have security enabled or not."
echo -e "-c OSD_URL\t, no defaults, effective when SECURITY_ENABLED=true."
echo -e "-r ref\t commit reference has id or branch name."
echo "--------------------------------------------------------------------------"
}

# Parse command-line arguments
while getopts "h:r:w:a:b:r:" opt; do
case $opt in
h)
usage
exit 1
;;
r)
REMOTE_REPO="$OPTARG"
;;
w)
WORKFLOW_NAME="$OPTARG"
;;
a)
OS_URL="$OPTARG"
;;
b)
OSD_URL="$OPTARG"
;;
c)
BRANCH_NAME="$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

# 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 matching_workflow
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=12 # Set the polling window period to be 1 hour

# Check if a matching workflow object was found
while [ -z "$matching_workflow" ] && [ $polling_run_id_retries -le $max_polling_run_id_retries ]; do
echo "Querying for the workflow run id..."
sleep 60 # Wait for 1 minute before polling for workflow run_id till it gets created

# 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")

# Extract the JSON object whose "name" field contains the string with a unique id of the workflow
matching_workflow=$(echo "$workflow_runs" | jq --arg unique_id "$UNIQUE_WORKFLOW_ID" '.workflow_runs[] | select(.name | contains($unique_id))')
((polling_run_id_retries++))

done
echo "matching_workflow: $matching_workflow"

if [ -n "$matching_workflow" ]; then
# Extract the "jobs_url" and "run_id" values from the matching object
jobs_url=$(echo "$matching_workflow" | jq -r '.jobs_url')
run_id=$(echo "$matching_workflow" | jq -r '.id')
echo "Jobs 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 "Workflow run details: $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 300 # Wait for 5 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

0 comments on commit e6deb18

Please sign in to comment.