Skip to content
Merged
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
57 changes: 57 additions & 0 deletions .githooks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Git Hooks
Copy link
Contributor

Choose a reason for hiding this comment

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

remove this one?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You mean this line or the whole file?

Copy link
Contributor

Choose a reason for hiding this comment

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

the file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Feel like it is helpful. Developers will have to do some manual install to enable this.


This directory contains Git hooks for the ExecuTorch repository.

## Pre-commit Hook

The pre-commit hook automatically updates the PyTorch commit pin in `.ci/docker/ci_commit_pins/pytorch.txt` whenever `torch_pin.py` is modified.

### How It Works

1. When you commit changes to `torch_pin.py`, the hook detects the change
2. It parses the `NIGHTLY_VERSION` field (e.g., `dev20251004`)
3. Converts it to a date string (e.g., `2025-10-04`)
4. Fetches the corresponding commit hash from the PyTorch nightly branch at https://github.com/pytorch/pytorch/tree/nightly
5. Updates `.ci/docker/ci_commit_pins/pytorch.txt` with the new commit hash
6. Automatically stages the updated file for commit

### Installation

To install the Git hooks, run:

```bash
.githooks/install.sh
```

This will copy the pre-commit hook to `.git/hooks/` and make it executable.

### Manual Usage

You can also run the update script manually at any time:

```bash
python .github/scripts/update_pytorch_pin.py
```

### Uninstalling

To remove the pre-commit hook:

```bash
rm .git/hooks/pre-commit
```

## Troubleshooting

If the hook fails during a commit:

1. Check that Python 3 is available in your PATH
2. Ensure you have internet connectivity to fetch commits from GitHub
3. Verify that the `NIGHTLY_VERSION` in `torch_pin.py` is in the correct format (`devYYYYMMDD`)
4. Make sure the corresponding nightly release exists in the PyTorch nightly branch

You can run the script manually to see detailed error messages:

```bash
python .github/scripts/update_pytorch_pin.py
```
23 changes: 23 additions & 0 deletions .githooks/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env bash

# Script to install Git hooks from .githooks directory

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GIT_DIR="$(git rev-parse --git-dir)"
HOOKS_DIR="${GIT_DIR}/hooks"

echo "Installing Git hooks..."

# Install pre-commit hook
echo "📦 Installing pre-commit hook..."
cp "${SCRIPT_DIR}/pre-commit" "${HOOKS_DIR}/pre-commit"
chmod +x "${HOOKS_DIR}/pre-commit"
echo "✅ pre-commit hook installed"

echo ""
echo "🎉 Git hooks installed successfully!"
echo ""
echo "The pre-commit hook will automatically update .ci/docker/ci_commit_pins/pytorch.txt"
echo "whenever you commit changes to torch_pin.py"
28 changes: 28 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#!/usr/bin/env bash

# Pre-commit hook to automatically update PyTorch commit pin when torch_pin.py changes

# Check if torch_pin.py is being committed
if git diff --cached --name-only | grep -q "^torch_pin.py$"; then
echo "🔍 Detected changes to torch_pin.py"
echo "📝 Updating PyTorch commit pin..."

# Run the update script
if python .github/scripts/update_pytorch_pin.py; then
# Check if pytorch.txt was modified
if ! git diff --quiet .ci/docker/ci_commit_pins/pytorch.txt; then
echo "✅ PyTorch commit pin updated successfully"
# Stage the updated file
git add .ci/docker/ci_commit_pins/pytorch.txt
echo "📌 Staged .ci/docker/ci_commit_pins/pytorch.txt"
else
echo "ℹ️ PyTorch commit pin unchanged"
fi
else
echo "❌ Failed to update PyTorch commit pin"
echo "Please run: python .github/scripts/update_pytorch_pin.py"
exit 1
fi
fi

exit 0
123 changes: 123 additions & 0 deletions .github/scripts/update_pytorch_pin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env python3

import json
import re
import sys
import urllib.request
from datetime import datetime


def parse_nightly_version(nightly_version):
"""
Parse NIGHTLY_VERSION (e.g., 'dev20251004') to date string (e.g., '2025-10-04').

Args:
nightly_version: String in format 'devYYYYMMDD'

Returns:
Date string in format 'YYYY-MM-DD'
"""
match = re.match(r"dev(\d{4})(\d{2})(\d{2})", nightly_version)
if not match:
raise ValueError(f"Invalid NIGHTLY_VERSION format: {nightly_version}")

year, month, day = match.groups()
return f"{year}-{month}-{day}"


def get_torch_nightly_version():
"""
Read NIGHTLY_VERSION from torch_pin.py.

Returns:
NIGHTLY_VERSION string
"""
with open("torch_pin.py", "r") as f:
content = f.read()

match = re.search(r'NIGHTLY_VERSION\s*=\s*["\']([^"\']+)["\']', content)
if not match:
raise ValueError("Could not find NIGHTLY_VERSION in torch_pin.py")

return match.group(1)


def get_commit_hash_for_nightly(date_str):
"""
Fetch commit hash from PyTorch nightly branch for a given date.

Args:
date_str: Date string in format 'YYYY-MM-DD'

Returns:
Commit hash string
"""
api_url = "https://api.github.com/repos/pytorch/pytorch/commits"
params = f"?sha=nightly&per_page=100"
url = api_url + params

req = urllib.request.Request(url)
req.add_header("Accept", "application/vnd.github.v3+json")
req.add_header("User-Agent", "ExecuTorch-Bot")

try:
with urllib.request.urlopen(req) as response:
commits = json.loads(response.read().decode())
except Exception as e:
print(f"Error fetching commits: {e}", file=sys.stderr)
sys.exit(1)

# Look for commit with title matching "{date_str} nightly release"
target_title = f"{date_str} nightly release"

for commit in commits:
commit_msg = commit.get("commit", {}).get("message", "")
# Check if the first line of commit message matches
first_line = commit_msg.split("\n")[0].strip()
if first_line == target_title or first_line.startswith(f"{date_str} nightly"):
return commit["sha"]

raise ValueError(
f"Could not find commit with title matching '{target_title}' in nightly branch"
)


def update_pytorch_pin(commit_hash):
"""
Update .ci/docker/ci_commit_pins/pytorch.txt with the new commit hash.

Args:
commit_hash: Commit hash to write
"""
pin_file = ".ci/docker/ci_commit_pins/pytorch.txt"
with open(pin_file, "w") as f:
f.write(f"{commit_hash}\n")
print(f"Updated {pin_file} with commit hash: {commit_hash}")


def main():
try:
# Read NIGHTLY_VERSION from torch_pin.py
nightly_version = get_torch_nightly_version()
print(f"Found NIGHTLY_VERSION: {nightly_version}")

# Parse to date string
date_str = parse_nightly_version(nightly_version)
print(f"Parsed date: {date_str}")

# Fetch commit hash from PyTorch nightly branch
commit_hash = get_commit_hash_for_nightly(date_str)
print(f"Found commit hash: {commit_hash}")

# Update the pin file
update_pytorch_pin(commit_hash)

print("Successfully updated PyTorch commit pin!")

except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)


if __name__ == "__main__":
main()
Loading