Skip to content
Open
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
85 changes: 85 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#!/bin/bash

# Pre-commit hook to enforce Windows compatibility and file size limits
#
# 1. Windows filenames: prevents characters that are reserved on Windows (< > : " | ? * \)
# so the repo can be cloned on Windows systems.
# 2. File size: rejects files larger than 10 MB. Many enterprise users mirror graphql-java
# into internal repositories that enforce file size limits.

# ANSI color codes for better output readability
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# Track if we found any errors
ERRORS_FOUND=0

echo "Running pre-commit checks..."

# Check 1: Windows-incompatible filenames
echo " Checking for Windows-incompatible filenames..."

# Windows reserved characters: < > : " | ? * \
# Note: We escape the backslash in the regex pattern
INVALID_CHARS='[<>:"|?*\\]'

# Get list of staged files
STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACR)

if [ -n "$STAGED_FILES" ]; then
# Check each staged file for invalid characters
INVALID_FILES=$(echo "$STAGED_FILES" | grep -E "$INVALID_CHARS" || true)

if [ -n "$INVALID_FILES" ]; then
echo -e "${RED}Error: The following files have Windows-incompatible characters in their names:${NC}"
echo "$INVALID_FILES" | while read -r file; do
echo " - $file"
done
echo -e "${YELLOW}Please rename these files to remove characters: < > : \" | ? * \\${NC}"
echo -e "${YELLOW}For ISO timestamps, replace colons with hyphens (e.g., 08:40:24 -> 08-40-24)${NC}"
ERRORS_FOUND=1
fi
fi

# Check 2: Files larger than 10MB
echo " Checking for files larger than 10MB..."

MAX_SIZE=$((10 * 1024 * 1024)) # 10 MB in bytes
LARGE_FILES=""

if [ -n "$STAGED_FILES" ]; then
while IFS= read -r file; do
if [ -f "$file" ]; then
# Try to get file size with cross-platform compatibility
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
if [ -z "$size" ]; then
echo -e "${YELLOW}Warning: Could not determine size of $file, skipping size check${NC}"
continue
fi
if [ "$size" -gt "$MAX_SIZE" ]; then
# Format size in human-readable format using awk (more portable than bc)
size_mb=$(awk "BEGIN {printf \"%.2f\", $size/1024/1024}")
LARGE_FILES="${LARGE_FILES} - $file (${size_mb} MB)\n"
fi
fi
done <<< "$STAGED_FILES"
fi

if [ -n "$LARGE_FILES" ]; then
echo -e "${RED}Error: The following files exceed 10MB:${NC}"
echo -e "$LARGE_FILES"
echo -e "${YELLOW}Please consider one of these options:${NC}"
echo -e "${YELLOW} 1. Split the file into smaller parts with suffixes .part1, .part2, etc.${NC}"
echo -e "${YELLOW} 2. Remove unnecessary content from the file${NC}"
ERRORS_FOUND=1
fi

# Exit with error if any checks failed
if [ "$ERRORS_FOUND" -eq 1 ]; then
echo -e "${RED}Pre-commit checks failed. Please fix the issues above and try again.${NC}"
exit 1
fi

echo " All pre-commit checks passed!"
exit 0
97 changes: 97 additions & 0 deletions .github/workflows/validate-files.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
name: Validate Files

# This workflow validates that all files in the repository comply with:
# 1. Windows filename compatibility — no reserved characters (< > : " | ? * \)
# so the repo can be cloned on Windows systems.
# 2. File size limits — no files larger than 10 MB. Many enterprise users mirror
# graphql-java into internal repositories that enforce file size limits.

on:
push:
branches:
- master
- '**'
pull_request:
branches:
- master
- 23.x
- 22.x
- 21.x
- 20.x
- 19.x

jobs:
validate-filenames-and-size:
runs-on: ubuntu-latest
name: Validate Windows Compatibility and File Sizes
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
fetch-depth: 0 # Fetch all history to check all files

- name: Check for Windows-incompatible filenames
run: |
echo "Checking for Windows-incompatible filenames..."

# Windows reserved characters: < > : " | ? * \
INVALID_CHARS='[<>:"|?*\\]'

# Get all files in the repository (excluding .git directory)
ALL_FILES=$(git ls-files)

# Check each file for invalid characters
INVALID_FILES=$(echo "$ALL_FILES" | grep -E "$INVALID_CHARS" || true)

if [ -n "$INVALID_FILES" ]; then
echo "::error::The following files have Windows-incompatible characters in their names:"
echo "$INVALID_FILES" | while read -r file; do
echo "::error file=${file}::File contains Windows-incompatible characters"
echo " - $file"
done
echo ""
echo "Please rename these files to remove characters: < > : \" | ? * \\"
echo "For ISO timestamps, replace colons with hyphens (e.g., 08:40:24 -> 08-40-24)"
exit 1
else
echo "✓ All filenames are Windows-compatible"
fi

- name: Check for files larger than 10MB
run: |
echo "Checking for files larger than 10MB..."

MAX_SIZE=$((10 * 1024 * 1024)) # 10 MB in bytes
LARGE_FILES=""

# Get all files in the repository (excluding .git directory)
ALL_FILES=$(git ls-files)

# Check each file's size
while IFS= read -r file; do
if [ -f "$file" ]; then
size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null)
if [ -z "$size" ]; then
echo "::warning file=${file}::Could not determine size of file"
continue
fi
if [ "$size" -gt "$MAX_SIZE" ]; then
size_mb=$(awk "BEGIN {printf \"%.2f\", $size/1024/1024}")
echo "::error file=${file}::File size (${size_mb} MB) exceeds 10MB limit"
LARGE_FILES="${LARGE_FILES}${file} (${size_mb} MB)\n"
fi
fi
done <<< "$ALL_FILES"

if [ -n "$LARGE_FILES" ]; then
echo ""
echo "The following files exceed 10MB:"
echo -e "$LARGE_FILES"
echo ""
echo "Please consider one of these options:"
echo " 1. Split the file into smaller parts with suffixes .part1, .part2, etc."
echo " 2. Remove unnecessary content from the file"
exit 1
else
echo "✓ All files are within the 10MB size limit"
fi
27 changes: 27 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,33 @@ therefore we avoid adding any new dependency.
access etc is out of scope.


## File Validation

This repository enforces file compatibility and size standards through both local Git hooks and CI checks.

### Local Git Hooks

To install the pre-commit hook locally, run:

```bash
./scripts/setup-hooks.sh
```

The pre-commit hook will automatically check for:

- **Windows-incompatible filenames**: Files with characters that are reserved on Windows (< > : " | ? * \) will be rejected. This ensures the repository can be cloned on Windows systems.

- **Large files**: Files larger than 10MB will be rejected. If you need to commit large files, consider:
- Splitting them into smaller parts (`.part1`, `.part2`, etc.)
- Reducing the file size

To bypass the hooks temporarily (not recommended), use `git commit --no-verify`.

### CI Validation

The same checks are also enforced by the "Validate Files" GitHub Action on all pull requests and pushes. This ensures that even if the local hook is bypassed, incompatible files will be caught during CI.


If you have any question please consider asking in our [Discussions](https://github.com/graphql-java/graphql-java/discussions). For bug reports or specific code related topics create a new issue.

Thanks!
Expand Down
22 changes: 22 additions & 0 deletions scripts/setup-hooks.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/bin/bash

# Script to install Git hooks for this repository
# This configures Git to use hooks from the .githooks directory

set -e

# Get the repository root directory
REPO_ROOT=$(git rev-parse --show-toplevel)

echo "Installing Git hooks for graphql-java..."

# Configure Git to use the .githooks directory
git config core.hooksPath "$REPO_ROOT/.githooks"

echo "✓ Git hooks installed successfully!"
echo ""
echo "The following hooks are now active:"
echo " - pre-commit: Checks for Windows-incompatible filenames and large files"
echo ""
echo "To disable hooks temporarily, use: git commit --no-verify"
echo "To uninstall hooks, run: git config --unset core.hooksPath"
14 changes: 14 additions & 0 deletions src/test/resources/large-schema-5-README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# large-schema-5 — Split File

`large-schema-5.graphqls` (11.3 MB) exceeds the 10 MB file-size limit and has been split into two parts.
The split is at a type boundary so each part contains only complete type definitions.

## Reassembly

```bash
# Linux / macOS
cat large-schema-5.graphqls.part1 large-schema-5.graphqls.part2 > large-schema-5.graphqls

# Windows (PowerShell)
Get-Content large-schema-5.graphqls.part1, large-schema-5.graphqls.part2 | Set-Content large-schema-5.graphqls
```
Loading
Loading