Skip to content

Commit 08df672

Browse files
committed
create gh action and workflow to update copyright year for files.
1 parent a5a0ccf commit 08df672

File tree

2 files changed

+149
-0
lines changed

2 files changed

+149
-0
lines changed
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
name: Update Copyright Year
2+
3+
on:
4+
schedule:
5+
- cron: "0 0 1 1 *"
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: write
10+
pull-requests: write
11+
12+
jobs:
13+
update-year-pr:
14+
runs-on: ubuntu-22.04
15+
steps:
16+
- name: Checkout repo
17+
uses: actions/checkout@v5
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: "3.11"
23+
24+
- name: Update copyright year
25+
run: python .github/scripts/update_copyright.py
26+
27+
- name: Check for changes
28+
id: check_changes
29+
run: |
30+
if git diff --quiet; then
31+
echo "has_changes=false" >> $GITHUB_OUTPUT
32+
else
33+
echo "has_changes=true" >> $GITHUB_OUTPUT
34+
fi
35+
36+
- name: Create PR
37+
if: steps.check_changes.outputs.has_changes == 'true'
38+
run: |
39+
YEAR=$(date +'%Y')
40+
BRANCH="update-copyright-$YEAR"
41+
42+
git config user.name "github-actions[bot]"
43+
git config user.email "github-actions[bot]@users.noreply.github.com"
44+
45+
git checkout -b "$BRANCH"
46+
git add .
47+
git commit -m "chore: update copyright year to $YEAR"
48+
git push --set-upstream origin "$BRANCH"
49+
50+
gh pr create \
51+
--title "chore: update copyright year to $YEAR" \
52+
--body "Automated update of copyright year to $YEAR." \
53+
--head "$BRANCH" \
54+
--base main \
55+
env:
56+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

utils/update_copyright_year.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Update copyright year in source files to the current year.
4+
"""
5+
import re
6+
import sys
7+
from datetime import datetime
8+
from pathlib import Path
9+
10+
# Set current year
11+
YEAR = str(datetime.now().year)
12+
13+
EXTENSIONS = {".py", ".md"}
14+
15+
# Directories to exclude
16+
EXCLUDE_DIRS = {
17+
".venv",
18+
"venv",
19+
"node_modules",
20+
".git",
21+
"__pycache__",
22+
".tox",
23+
"dist",
24+
"build",
25+
".egg-info",
26+
}
27+
28+
# Regex patterns to match copyright lines
29+
COPYRIGHT_PATTERNS = [
30+
re.compile(r"(# Copyright )(\d{4})( The HuggingFace Team\.)"),
31+
re.compile(r"(# Copyright \(c\) )(\d{4})( The HuggingFace Team\.)"),
32+
re.compile(r"(Copyright )(\d{4})( The HuggingFace Team\.)"),
33+
re.compile(r"(Copyright \(c\) )(\d{4})( The HuggingFace Team\.)"),
34+
]
35+
36+
37+
def should_exclude(path: Path) -> bool:
38+
"""Check if path should be excluded."""
39+
return any(excluded in path.parts for excluded in EXCLUDE_DIRS)
40+
41+
42+
def update_file(file_path: Path) -> int:
43+
"""Update copyright year in a single file. Returns number of updates."""
44+
try:
45+
content = file_path.read_text(encoding="utf-8")
46+
except Exception as e:
47+
print(f"Warning: Could not read {file_path}: {e}", file=sys.stderr)
48+
return 0
49+
50+
new_content = content
51+
total_count = 0
52+
53+
for pattern in COPYRIGHT_PATTERNS:
54+
new_content, count = pattern.subn(rf"\g<1>{YEAR}\g<3>", new_content)
55+
total_count += count
56+
57+
if total_count > 0:
58+
try:
59+
file_path.write_text(new_content, encoding="utf-8")
60+
print(f"✓ Updated {total_count} line(s) in {file_path}")
61+
except Exception as e:
62+
print(f"Error: Could not write {file_path}: {e}", file=sys.stderr)
63+
return 0
64+
65+
return total_count
66+
67+
68+
def main():
69+
repo_root = Path(".").resolve()
70+
71+
print(f"Updating copyright to {YEAR}...")
72+
73+
total_files = 0
74+
total_updates = 0
75+
76+
for file_path in repo_root.rglob("*"):
77+
if not file_path.is_file() or should_exclude(file_path):
78+
continue
79+
80+
if file_path.suffix in EXTENSIONS:
81+
updates = update_file(file_path)
82+
if updates > 0:
83+
total_files += 1
84+
total_updates += updates
85+
86+
print(f"\nSummary: Updated {total_updates} line(s) in {total_files} file(s)")
87+
88+
# Exit with 0 if updates were made, 1 if no updates needed
89+
return 0 if total_updates > 0 else 1
90+
91+
92+
if __name__ == "__main__":
93+
sys.exit(main())

0 commit comments

Comments
 (0)