Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions .github/scripts/commit_hunter.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#!/usr/bin/env bash
#
# .github/scripts/commit_hunter.sh
#
# Arg1: the full GitHub comment body
#
set -euo pipefail

COMMENT="$1"

# 1) Remove leading /gitcompare line
BODY="${COMMENT#*\/gitcompare}"

# 2) Normalize Windows line endings
BODY="${BODY//$'\r'/}"

# 3) Split on the first line containing only dashes (allowing spaces)
# We use awk for robustness
GOOD=$(printf '%s\n' "$BODY" \
| awk 'BEGIN{sep="---"}
$0 ~ "^[[:space:]]*" sep "[[:space:]]*$" { exit }
{print}')

BAD=$(printf '%s\n' "$BODY" \
| awk 'BEGIN{sep="---"}
$0 ~ "^[[:space:]]*" sep "[[:space:]]*$" {found=1; next}
found {print}')

# 4) Trim blank lines
trim() { printf '%s\n' "$1" | sed '/^[[:space:]]*$/d'; }
GOOD=$(trim "$GOOD")
BAD=$(trim "$BAD")

# >>> Now you have two variables, GOOD and BAD, containing exactly what you need.
# For example:
echo "Comparing these SHAs from GOOD:"
echo "$GOOD" | grep -oE '[0-9a-f]{7,}'
echo
echo "…against BAD:"
echo "$BAD" | grep -oE '[0-9a-f]{7,}'
echo

# 5) Call your existing compare routine.
# Pass GOOD and BAD as multi-line arguments:
./commit_hunter_core.sh "$GOOD" "$BAD"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is commit_hunter_core.sh file?

34 changes: 34 additions & 0 deletions .github/scripts/parse_comment.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
set -e

COMMENT="$1"

# Remove the command prefix
COMMENT=${COMMENT#.ch_gitcompare}

# Extract arguments
if [[ $COMMENT =~ --good_build[[:space:]]+(.*)[[:space:]]+--bad_build[[:space:]]+(.*) ]]; then
GOOD_BUILD="${BASH_REMATCH[1]}"
BAD_BUILD="${BASH_REMATCH[2]}"
else
echo "Error: Invalid format. Please use: .ch_gitcompare --good_build <good_build> --bad_build <bad_build>"
exit 1
fi

# Clean whitespace and quotes
GOOD_BUILD=$(echo "$GOOD_BUILD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^"//;s/"$//')
BAD_BUILD=$(echo "$BAD_BUILD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^"//;s/"$//')

# Validate
if [ -z "$GOOD_BUILD" ] || [ -z "$BAD_BUILD" ]; then
echo "Error: One of the builds is empty"
exit 1
fi

echo "good_build<<EOF" >> $GITHUB_OUTPUT
echo "$GOOD_BUILD" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT

echo "bad_build<<EOF" >> $GITHUB_OUTPUT
echo "$BAD_BUILD" >> $GITHUB_OUTPUT
echo "EOF" >> $GITHUB_OUTPUT
20 changes: 20 additions & 0 deletions .github/scripts/parse_urls.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/bin/bash
set -e

OUTPUT_FILE="./CommitHunter/output.txt"

if [ -f "$OUTPUT_FILE" ]; then
echo "Found output file"
cat "$OUTPUT_FILE"

url_openj9=$(grep "OpenJ9:" "$OUTPUT_FILE" | awk '{print $2}')
url_omr=$(grep "OMR:" "$OUTPUT_FILE" | awk '{print $2}')
url_jcl=$(grep "JCL:" "$OUTPUT_FILE" | awk '{print $2}')

echo "url_openj9=$url_openj9" >> $GITHUB_OUTPUT
echo "url_omr=$url_omr" >> $GITHUB_OUTPUT
echo "url_jcl=$url_jcl" >> $GITHUB_OUTPUT
else
echo "Error: output.txt not found"
exit 1
fi
22 changes: 22 additions & 0 deletions .github/scripts/post_comment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os
import sys
from github import Github

try:
with open("comment.md", "r", encoding="utf-8") as f:
comment_body = f.read()

token = os.environ["GITHUB_TOKEN"]
repo_name = os.environ["GITHUB_REPOSITORY"]
issue_number = int(os.environ["ISSUE_NUMBER"])

g = Github(token)
repo = g.get_repo(repo_name)
issue = repo.get_issue(number=issue_number)

comment = issue.create_comment(comment_body)
print(f"✅ Comment created: {comment.html_url}")

except Exception as e:
print(f"❌ Error creating comment: {e}")
sys.exit(1)
155 changes: 155 additions & 0 deletions .github/workflows/gitcompare.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
name: GitCompare

on:
issue_comment:
types: [created]

jobs:
parse-comment:
if: startsWith(github.event.comment.body, '.ch_gitcompare')
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
outputs:
good_build: ${{ steps.parse.outputs.good_build }}
bad_build: ${{ steps.parse.outputs.bad_build }}
steps:
- name: Parse comment
id: parse
env:
COMMENT_BODY: ${{ github.event.comment.body }}
run: |
echo "Comment body: $COMMENT_BODY"
COMMENT=${COMMENT_BODY#.ch_gitcompare}

if [[ $COMMENT =~ --good_build[[:space:]]+(.*)[[:space:]]+--bad_build[[:space:]]+(.*) ]]; then
GOOD_BUILD="${BASH_REMATCH[1]}"
BAD_BUILD="${BASH_REMATCH[2]}"
else
echo "Error: Invalid format. Please use: .ch_gitcompare --good_build <good_build> --bad_build <bad_build>"
exit 1
fi

GOOD_BUILD=$(echo "$GOOD_BUILD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^"//;s/"$//')
BAD_BUILD=$(echo "$BAD_BUILD" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | sed 's/^"//;s/"$//')

echo "Good build: '$GOOD_BUILD'"
echo "Bad build: '$BAD_BUILD'"

if [ -z "$GOOD_BUILD" ] || [ -z "$BAD_BUILD" ]; then
echo "Error: Invalid format. Please use: .ch_gitcompare --good_build <good_build> --bad_build <bad_build>"
exit 1
fi

{
echo "good_build<<EOF"
echo "$GOOD_BUILD"
echo "EOF"
} >> $GITHUB_OUTPUT

{
echo "bad_build<<EOF"
echo "$BAD_BUILD"
echo "EOF"
} >> $GITHUB_OUTPUT

compare:
needs: parse-comment
runs-on: ubuntu-latest
permissions:
contents: read
issues: write
pull-requests: write
steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Run CommitHunter (Python)
id: run_commit_hunter
env:
GOOD_BUILD: ${{ needs.parse-comment.outputs.good_build }}
BAD_BUILD: ${{ needs.parse-comment.outputs.bad_build }}
run: |
cd CommitHunter
echo "$GOOD_BUILD" > good.txt
echo "$BAD_BUILD" > bad.txt
echo "Running commit_hunter.py..."
python3 commit_hunter.py "$(cat good.txt)" "$(cat bad.txt)" > output.txt
echo "CommitHunter output:"
cat output.txt

- name: Parse URLs from output
id: parse_urls
run: |
if [ -f "./CommitHunter/output.txt" ]; then
echo "Found output file, parsing URLs..."
cat ./CommitHunter/output.txt

url_openj9=$(grep "OpenJ9:" ./CommitHunter/output.txt | awk '{print $2}')
url_omr=$(grep "OMR:" ./CommitHunter/output.txt | awk '{print $2}')
url_jcl=$(grep "JCL:" ./CommitHunter/output.txt | awk '{print $2}')

echo "Parsed URLs:"
echo "OpenJ9: $url_openj9"
echo "OMR: $url_omr"
echo "JCL: $url_jcl"

echo "url_openj9=$url_openj9" >> $GITHUB_OUTPUT
echo "url_omr=$url_omr" >> $GITHUB_OUTPUT
echo "url_jcl=$url_jcl" >> $GITHUB_OUTPUT
else
echo "Error: output.txt not found in CommitHunter directory"
ls -la ./CommitHunter/
exit 1
fi

- name: Prepare comment
run: |
echo "## 🔍 GitCompare Results" > comment.md
echo "" >> comment.md
echo "### OpenJ9 Changes" >> comment.md
echo "${{ steps.parse_urls.outputs.url_openj9 }}" >> comment.md
echo "" >> comment.md
echo "### OMR Changes" >> comment.md
echo "${{ steps.parse_urls.outputs.url_omr }}" >> comment.md
echo "" >> comment.md
echo "### JCL Changes" >> comment.md
echo "${{ steps.parse_urls.outputs.url_jcl }}" >> comment.md
echo "" >> comment.md
echo "> 💡 **Note:** These links show the differences between the specified builds."
cat comment.md

- name: Comment on PR
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_REPOSITORY: ${{ github.repository }}
ISSUE_NUMBER: ${{ github.event.issue.number }}
run: |
pip install PyGithub
python3 <<EOF
import os
import sys
from github import Github

try:
with open("comment.md", "r", encoding="utf-8") as f:
comment_body = f.read()

token = os.environ["GITHUB_TOKEN"]
repo_name = os.environ["GITHUB_REPOSITORY"]
issue_number = int(os.environ["ISSUE_NUMBER"])

g = Github(token)
repo = g.get_repo(repo_name)
issue = repo.get_issue(number=issue_number)

comment = issue.create_comment(comment_body)
print(f"✅ Comment created successfully: {comment.html_url}")

except Exception as e:
print(f"❌ Error creating comment: {e}")
print(f"Error type: {type(e).__name__}")
sys.exit(1)
EOF
71 changes: 71 additions & 0 deletions CommitHunter/commit_hunter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import re
import sys

def parse_java_version(version_output):
result = []

print(f"Parsing version output: {version_output}", file=sys.stderr)

openjdk_match = re.search(r'openjdk\s+version\s+\"?(\d+)\.\d+\.\d+-beta', version_output)
if openjdk_match:
result.append(f"openjdk_version={openjdk_match.group(1)}")

openj9_match = re.search(r'OpenJ9\s*-\s*([0-9a-f]+)', version_output)
if openj9_match:
result.append(f"openj9_commit={openj9_match.group(1)}")

omr_match = re.search(r'OMR\s*-\s*([0-9a-f]+)', version_output)
if omr_match:
result.append(f"omr_commit={omr_match.group(1)}")

jcl_match = re.search(r'JCL\s*-\s*([0-9a-f]+)', version_output)
if jcl_match:
result.append(f"jcl_commit={jcl_match.group(1)}")

return "\n".join(result)

def generate_compare_urls(good_info, bad_info):
good = {}
bad = {}

for line in good_info.strip().splitlines():
if '=' in line:
key, value = line.strip().split('=', 1)
good[key] = value

for line in bad_info.strip().splitlines():
if '=' in line:
key, value = line.strip().split('=', 1)
bad[key] = value

print(f"OpenJ9: https://github.com/eclipse-openj9/openj9/compare/{good['openj9_commit']}...{bad['openj9_commit']}")
print(f"OMR: https://github.com/eclipse-omr/omr/compare/{good['omr_commit']}...{bad['omr_commit']}")
print(f"JCL: https://github.com/ibmruntimes/openj9-openjdk-jdk{good['openjdk_version']}/compare/{good['jcl_commit']}...{bad['jcl_commit']}")

if __name__ == "__main__":
if len(sys.argv) != 3:
print("Usage: python commit_hunter.py <good_build> <bad_build>")
sys.exit(1)

good_build = sys.argv[1]
bad_build = sys.argv[2]

print(f"Good build: {good_build}", file=sys.stderr)
print(f"Bad build: {bad_build}", file=sys.stderr)

good_info = parse_java_version(good_build)
bad_info = parse_java_version(bad_build)

print(f"Good info: {good_info}", file=sys.stderr)
print(f"Bad info: {bad_info}", file=sys.stderr)

required_fields = ["openjdk_version", "openj9_commit", "omr_commit", "jcl_commit"]
for field in required_fields:
if not any(line.startswith(f"{field}=") for line in good_info.splitlines()):
print(f"Error: Missing required field: {field}", file=sys.stderr)
sys.exit(1)
if not any(line.startswith(f"{field}=") for line in bad_info.splitlines()):
print(f"Error: Missing required field: {field}", file=sys.stderr)
sys.exit(1)

generate_compare_urls(good_info, bad_info)
Loading