-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
test json diff workflow #14806
Merged
Merged
test json diff workflow #14806
Changes from 4 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
1dc31a0
add cross repo dispatch to trigger indexer processor integ tests
yuunlimm 4980b1b
convert to bash script for readability
yuunlimm 2c61b56
temp to check new file behavior
yuunlimm 0bc93b4
add check if workflow run exists
yuunlimm fec7122
remove testing txn
yuunlimm 0ffb969
skip auth if dispatch isn't needed
yuunlimm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
|
||
name: Trigger Processor Tests on JSON Change | ||
|
||
on: | ||
workflow_dispatch: | ||
pull_request: # Trigger on PR-level events | ||
branches: | ||
- main | ||
|
||
# the required permissions to request the ID token | ||
permissions: | ||
id-token: write # This is required for GCP authentication | ||
contents: read # Ensure the workflow has access to repository contents | ||
|
||
jobs: | ||
dispatch_event: | ||
runs-on: runs-on,cpu=64,family=c7,hdd=500,image=aptos-ubuntu-x64,run-id=${{ github.run_id }} | ||
|
||
steps: | ||
- name: Checkout the repository | ||
uses: actions/checkout@v4 | ||
with: | ||
ref: ${{ github.event.pull_request.head.ref }} | ||
|
||
- name: Set up Rust | ||
uses: aptos-labs/aptos-core/.github/actions/rust-setup@main | ||
with: | ||
GIT_CREDENTIALS: ${{ secrets.GIT_CREDENTIALS }} | ||
|
||
# Install necessary system dependencies | ||
- name: Install system dependencies | ||
run: | | ||
sudo apt-get update | ||
sudo apt-get install build-essential libssl-dev pkg-config | ||
|
||
# Ensure Rust is updated | ||
- name: Update Rust toolchain | ||
run: rustup update | ||
|
||
- name: Run CLI to Generate JSON Files | ||
run: | | ||
cd ecosystem/indexer-grpc/indexer-transaction-generator | ||
cargo run -- --testing-folder ./example_tests --output-folder ../indexer-test-transactions/new_json_transactions | ||
|
||
- name: Install jq | ||
run: sudo apt-get install jq # Ensure jq is installed for JSON processing | ||
|
||
# TODO: improve this step to be easily maintainable and extensible | ||
# Prepare Original and New JSON Files | ||
- name: Prepare and Clean JSON Files | ||
run: | | ||
cd ecosystem/indexer-grpc/indexer-test-transactions | ||
|
||
for folder in json_transactions/scripted_transactions new_json_transactions/scripted_transactions; do | ||
for file in $folder/*.json; do | ||
echo "Processing $file..." | ||
base_file=$(basename "$file") | ||
|
||
jq 'del(.timestamp, | ||
rtso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.version, | ||
.info.hash, | ||
.info.stateChangeHash, | ||
.info.accumulatorRootHash, | ||
.info.changes[].writeResource.stateKeyHash, | ||
.info.changes[].writeResource.type.address, | ||
.info.changes[].writeResource.address, | ||
rtso marked this conversation as resolved.
Show resolved
Hide resolved
|
||
.info.changes[].writeTableItem.stateKeyHash, | ||
.info.changes[].writeTableItem.data.key, | ||
.info.changes[].writeTableItem.data.value, | ||
.epoch, | ||
.blockHeight, | ||
.sizeInfo, | ||
.user.request.sender, | ||
.user.request.expirationTimestampSecs.seconds, | ||
.user.request.signature.ed25519.publicKey, | ||
.user.request.signature.ed25519.signature) | ||
| (.info.changes[].writeResource.data |= | ||
if type == "string" then | ||
(fromjson | ||
| del(.authentication_key) | ||
| walk(if type == "object" and has("addr") then del(.addr) else . end) | ||
| tostring) | ||
else . end)' "$file" > "$folder/cleaned_$base_file" | ||
done | ||
done | ||
|
||
- name: Compare JSON Files Across Multiple Folders | ||
id: diff_check | ||
run: | | ||
. scripts/indexer_test_txns_compare_and_diff.sh | ||
|
||
- name: Handle New Files and Differences | ||
run: | | ||
echo "Checking outputs from diff_check step..." | ||
echo "New file found: ${{ steps.diff_check.outputs.new_file_found }}" | ||
echo "Diff found: ${{ steps.diff_check.outputs.diff_found }}" | ||
|
||
if [ "${{ steps.diff_check.outputs.new_file_found }}" == "true" ]; then | ||
echo "New JSON files detected:" | ||
echo "${{ steps.diff_check.outputs.new_files }}" # Print all new files with paths | ||
exit 0 # Fail the workflow to enforce manual review | ||
elif [ "${{ steps.diff_check.outputs.diff_found }}" == "true" ]; then | ||
echo "Differences detected. Proceeding with dispatch event." | ||
echo "Modified files:" | ||
echo "${{ steps.diff_check.outputs.modified_files }}" # Print modified files with paths | ||
else | ||
echo "No differences or new files detected." | ||
exit 0 # Proceed successfully only if no new files or differences are found | ||
fi | ||
|
||
- id: auth | ||
yuunlimm marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uses: "google-github-actions/auth@v2" | ||
with: | ||
workload_identity_provider: ${{ secrets.GCP_WORKLOAD_IDENTITY_PROVIDER }} | ||
service_account: ${{ secrets.GCP_SERVICE_ACCOUNT_EMAIL }} | ||
|
||
- name: Log active service account email | ||
run: | | ||
gcloud auth list --filter=status:ACTIVE --format="value(account)" | ||
- id: 'secrets' | ||
uses: 'google-github-actions/get-secretmanager-secrets@v2' | ||
with: | ||
secrets: |- | ||
token:aptos-ci/github-actions-repository-dispatch | ||
|
||
# Conditionally Dispatch Event to Processor Repo if Differences Found | ||
- name: Dispatch Event to Processor Repo | ||
if: steps.diff_check.outputs.diff_found == 'true' && steps.diff_check.outputs.new_file_found == 'false' | ||
uses: peter-evans/[email protected] | ||
with: | ||
TOKEN: '${{ steps.secrets.outputs.token }}' | ||
repository: 'aptos-labs/aptos-indexer-processors' | ||
event-type: 'test-txn-json-change-detected' | ||
client-payload: '{"commit_hash": "${{ github.sha }}"}' | ||
|
||
# Poll Processor Repo for Workflow Run Status and Memorize Run ID to check the job status | ||
- name: Poll for Workflow Run and Wait for Job Completion | ||
if: steps.diff_check.outputs.diff_found == 'true' && steps.diff_check.outputs.new_file_found == 'false' | ||
id: poll_status | ||
run: | | ||
. scripts/indexer_processor_tests_status_poll.sh | ||
env: | ||
GITHUB_TOKEN: ${{ steps.secrets.outputs.token }} # Pass the correct GitHub token | ||
GITHUB_SHA: ${{ github.sha }} |
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
#!/bin/bash | ||
|
||
# Poll for Workflow Run and Wait for Job Completion | ||
|
||
# Unique identifier for the run (commit_hash or UUID passed via event payload) | ||
UUID="${GITHUB_SHA}" | ||
|
||
# If a run_id is already known, use it directly to check the run status | ||
if [ -f ".cached_run_id" ]; then | ||
run_id=$(cat .cached_run_id) | ||
echo "Using cached run_id: $run_id" | ||
else | ||
echo "Polling for the workflow run with UUID: $UUID." | ||
|
||
attempts=0 | ||
max_attempts=5 # Number of attempts to find the run_id | ||
sleep_interval=30 # Time to wait between attempts (in seconds) | ||
|
||
while [ $attempts -lt $max_attempts ]; do | ||
echo "Polling for the workflow run. Attempt $((attempts+1)) of $max_attempts..." | ||
|
||
# Get the workflow runs for the repository | ||
response=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" \ | ||
"https://api.github.com/repos/aptos-labs/aptos-indexer-processors/actions/runs?event=repository_dispatch&branch=main") | ||
|
||
# Check if the workflow_runs array exists | ||
workflow_runs=$(echo "$response" | jq -r '.workflow_runs') | ||
if [ "$workflow_runs" == "null" ] || [ -z "$workflow_runs" ]; then | ||
echo "No workflow runs found. Response from GitHub API:" | ||
echo "$response" # Output the raw response for debugging | ||
echo "Retrying in $sleep_interval seconds..." | ||
attempts=$((attempts + 1)) | ||
sleep $sleep_interval | ||
continue | ||
fi | ||
|
||
# Filter the workflow run by the unique run-name commit hash | ||
run_id=$(echo "$workflow_runs" | jq -r ".[] | select(.name | test(\"$UUID\")) | .id") | ||
|
||
if [ -n "$run_id" ]; then | ||
echo "Found workflow run with ID: $run_id" | ||
echo "$run_id" > .cached_run_id # Save the run_id to cache | ||
break | ||
else | ||
echo "No matching workflow run found yet. Retrying in $sleep_interval seconds..." | ||
attempts=$((attempts + 1)) | ||
sleep $sleep_interval | ||
fi | ||
done | ||
fi | ||
|
||
# If we still don't have a run_id, exit the job | ||
if [ -z "$run_id" ]; then | ||
echo "Workflow run not found after $max_attempts attempts. Exiting." | ||
exit 1 | ||
fi | ||
|
||
# Now that we have the run_id (cached or newly found), proceed to poll job status | ||
jobs_url="https://api.github.com/repos/aptos-labs/aptos-indexer-processors/actions/runs/${run_id}/jobs" | ||
|
||
# Poll the job status until completion | ||
job_completed=false | ||
max_job_attempts=20 # Adjust based on how long you expect the job to run | ||
job_attempts=0 | ||
sleep_interval=60 # Adjust polling interval as needed | ||
|
||
while [ "$job_completed" == false ] && [ $job_attempts -lt $max_job_attempts ]; do | ||
echo "Polling for job status. Attempt $((job_attempts+1)) of $max_job_attempts..." | ||
jobs_response=$(curl -s -H "Authorization: Bearer ${GITHUB_TOKEN}" "$jobs_url") | ||
|
||
# Check if the jobs array exists | ||
jobs=$(echo "$jobs_response" | jq -r '.jobs') | ||
if [ "$jobs" == "null" ] || [ -z "$jobs" ]; then | ||
echo "No jobs found in the workflow run. Response from GitHub API:" | ||
echo "$jobs_response" # Output the raw response for debugging | ||
exit 1 | ||
fi | ||
|
||
# Loop through the jobs and check their status | ||
for job in $(echo "$jobs" | jq -r '.[] | @base64'); do | ||
_jq() { | ||
echo "${job}" | base64 --decode | jq -r "${1}" | ||
} | ||
|
||
job_name=$(_jq '.name') | ||
job_id=$(_jq '.id') | ||
job_status=$(_jq '.status') | ||
job_conclusion=$(_jq '.conclusion') | ||
|
||
echo "Checking job: $job_name (Job ID: $job_id)" | ||
echo "Job status: $job_status" | ||
echo "Job conclusion: $job_conclusion" | ||
|
||
# Check if the job has completed | ||
if [ "$job_status" == "completed" ]; then | ||
job_completed=true | ||
if [ "$job_conclusion" == "success" ]; then | ||
echo "Job completed successfully!" | ||
exit 0 # Exit with success | ||
else | ||
echo "Job failed!" | ||
exit 1 # Exit with failure | ||
fi | ||
fi | ||
done | ||
|
||
# Sleep before the next polling attempt | ||
echo "Job is still in progress. Waiting $sleep_interval seconds before polling again..." | ||
sleep $sleep_interval | ||
job_attempts=$((job_attempts + 1)) | ||
done | ||
|
||
# If the job hasn't completed within the allowed attempts, exit with an error | ||
if [ "$job_completed" == false ]; then | ||
echo "Job did not complete within the expected time. Exiting with failure." | ||
exit 1 | ||
fi |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#!/bin/bash | ||
|
||
# Function to compare and handle diff logic | ||
compare_and_diff() { | ||
local generated_file=$1 | ||
local original_file=$2 | ||
|
||
echo "Modified file path: $generated_file" | ||
echo "Original file path: $original_file" | ||
|
||
if [ -f "$original_file" ]; then | ||
echo "Original file exists, comparing with modified file." | ||
# Run diff and capture the output | ||
diff_output=$(diff -u "$original_file" "$generated_file" || true) | ||
|
||
if [ -n "$diff_output" ]; then | ||
echo "Differences found in $generated_file" | ||
diff_found=true | ||
modified_files="${modified_files}${generated_file}\n" # Append the full path of the modified file | ||
echo "Diff output:" | ||
echo "$diff_output" | ||
else | ||
echo "No differences found for $generated_file." | ||
fi | ||
else | ||
echo "New file detected: $generated_file (no corresponding original file found)" | ||
new_file_found=true | ||
new_files="${new_files}${generated_file}\n" # Append the full path of the new file | ||
|
||
# Treat as new file, but still run a diff (compare with /dev/null) | ||
diff_output=$(diff -u /dev/null "$generated_file" || true) | ||
if [ -n "$diff_output" ]; then | ||
echo "New file with diff found in $generated_file" | ||
echo "Diff output for new file:" | ||
echo "$diff_output" | ||
fi | ||
fi | ||
} | ||
|
||
|
||
# Initialize the flags | ||
diff_found=false | ||
new_file_found=false | ||
new_files="" | ||
modified_files="" | ||
|
||
cd ecosystem/indexer-grpc/indexer-test-transactions || exit 1 | ||
|
||
echo "Starting comparison between new and original JSON files." | ||
|
||
# C heck if the new_json_transactions folder exists | ||
if [ ! -d "new_json_transactions" ]; then | ||
echo "Directory new_json_transactions does not exist. Exiting." | ||
exit 1 | ||
fi | ||
|
||
# Loop over all subdirectories inside new_json_transactions | ||
for folder in new_json_transactions/*; do | ||
if [ -d "$folder" ]; then # Ensure it's a directory | ||
echo "Processing folder: $folder" | ||
|
||
# Check if the folder is for imported transactions | ||
if [[ "$folder" == *"imported_"* ]]; then | ||
# For imported transactions, process all files without any 'modified_' check | ||
for file in "$folder"/*.json; do | ||
if [ -f "$file" ]; then | ||
echo "Processing imported file: $file" | ||
base_file=$(basename "$file" .json) | ||
original_file="../indexer-test-transactions/json_transactions/$(basename $folder)/${base_file}.json" | ||
compare_and_diff "$file" "$original_file" | ||
fi | ||
done | ||
else | ||
# For scripted transactions, only process files that are prefixed with 'cleaned_' | ||
for file in "$folder"/cleaned_*.json; do | ||
if [ -f "$file" ]; then | ||
echo "Processing scripted file: $file" | ||
base_file=$(basename "$file" .json) | ||
original_file="../indexer-test-transactions/json_transactions/$(basename $folder)/${base_file}.json" | ||
compare_and_diff "$file" "$original_file" | ||
fi | ||
done | ||
fi | ||
else | ||
echo "Folder $folder is not a valid directory." | ||
fi | ||
done | ||
|
||
# Print all new files if found | ||
if [ "$new_file_found" = "true" ] && [ -n "$new_files" ]; then | ||
echo "New files detected:" | ||
echo -e "$new_files" | ||
else | ||
echo "No new files detected." | ||
fi | ||
|
||
# Print all modified files if found | ||
if [ "$diff_found" = "true" ] && [ -n "$modified_files" ]; then | ||
echo "Modified files detected:" | ||
echo -e "$modified_files" | ||
else | ||
echo "No modified files detected." | ||
fi | ||
|
||
# Debugging logs before setting outputs | ||
echo "diff_found=$diff_found" | ||
echo "new_file_found=$new_file_found" | ||
echo "new_files=$new_files" | ||
echo "modified_files=$modified_files" | ||
|
||
# Set output flags | ||
echo "diff_found=$diff_found" >> $GITHUB_OUTPUT | ||
echo "new_file_found=$new_file_found" >> $GITHUB_OUTPUT | ||
echo "new_files=$new_files" >> $GITHUB_OUTPUT # Store new files as output | ||
echo "modified_files=$modified_files" >> $GITHUB_OUTPUT # Store modified files as output | ||
echo "Comparison completed." |
Oops, something went wrong.
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i feel we can use python: managing or ignoring some fields are easier.