A GitHub Action to validate SPDX copyright headers on pull requests. Ensures all new and modified files have correct SPDX headers with proper year formatting.
✅ New Files: Validates that new files include SPDX headers with the current year
✅ Modified Files: Ensures modified files update to current year or use proper year ranges
✅ File Creation Detection: Automatically detects original file creation year from git history
✅ Flexible Patterns: Support for including/excluding files by glob patterns
✅ Bilingual Messages: Error messages in both English and Simplified Chinese
✅ Multi-Format Support: Works with // and # style comments
✅ Dual Header Formats: Supports both SPDX-FileCopyrightText and traditional Copyright (C) formats
This action validates two copyright header formats:
-
SPDX Format (Recommended):
// SPDX-FileCopyrightText: 2026 Your Company Name // SPDX-License-Identifier: GPL-3.0-or-later -
Traditional Copyright Format:
// Copyright (C) 2026 Your Company Name // SPDX-License-Identifier: GPL-3.0-or-later
Both formats follow the same year validation rules.
- New files must include an SPDX header with the current year
- Modified files must update their SPDX header year:
- Same year as creation: Use single year format (e.g.,
2026) - Different year from creation: Use year range format (e.g.,
2023-2026)
- Same year as creation: Use single year format (e.g.,
- SPDX license identifier lines must be present
- Header and license lines must use matching comment prefixes
Add to your .github/workflows/spdx-check.yml:
name: SPDX Header Check
on:
pull_request:
branches: [main]
jobs:
spdx-check:
runs-on: ubuntu-latest
steps:
- uses: zccrs/github-actions-spdx-checker@v1
with:
base: origin/main
include: '*.py,*.js,*.ts,*.jsx,*.tsx,*.java,*.cpp,*.c,*.h,*.hpp,*.go,*.rs,*.rb,*.php,*.sh,*.xml,*.yaml,*.yml,*.json,CMakeLists.txt,Makefile'
exclude: 'vendor/**,node_modules/**'- base (optional): Base reference to diff against (default:
origin/main) - include (optional): Comma-separated glob patterns to include (default: all files)
- exclude (optional): Comma-separated glob patterns to exclude (default: none)
- year (optional): Current year for validation (default: current UTC year)
- debug (optional): Enable debug mode with detailed output for each file (default:
false) - all-files (optional): Check all files in repository instead of only changed files (default:
false) - holder (optional): Only check files with matching copyright holder. Supports wildcards:
*UnionTech*- Matches any holder containing "UnionTech"*Corp- Matches holders ending with "Corp"Microsoft*- Matches holders starting with "Microsoft"Company Name- Exact match for "Company Name"- Empty (default) - Checks all files regardless of holder
Check all files in repository:
- uses: zccrs/github-actions-spdx-checker@v1
with:
all-files: true
exclude: 'vendor/**,node_modules/**'Enable debug mode:
- uses: zccrs/github-actions-spdx-checker@v1
with:
debug: trueCheck only specific copyright holder:
- uses: zccrs/github-actions-spdx-checker@v1
with:
holder: '*UnionTech*'Check with exact copyright holder match:
- uses: zccrs/github-actions-spdx-checker@v1
with:
holder: 'UnionTech Software Technology Co., Ltd.'Multiple holder patterns (check multiple companies):
# Option 1: Use broader wildcard pattern
- uses: zccrs/github-actions-spdx-checker@v1
with:
holder: '*Corp*' # Matches "Alice Corp", "Microsoft Corporation", etc.
# Option 2: Use specific pattern
- uses: zccrs/github-actions-spdx-checker@v1
with:
holder: '*Software*' # Matches any holder containing "Software"Combine holder filtering with other options:
- uses: zccrs/github-actions-spdx-checker@v1
with:
holder: '*UnionTech*'
debug: true
all-files: true
exclude: 'vendor/**,node_modules/**'The action works with any file type using // or # comment styles. Common examples include:
Programming Languages:
- Python:
.py - JavaScript/TypeScript:
.js,.ts,.jsx,.tsx - Java:
.java - C/C++:
.c,.cpp,.h,.hpp - Go:
.go - Rust:
.rs - Ruby:
.rb - PHP:
.php - Shell:
.sh,.bash
Configuration & Data Formats:
- XML:
.xml - YAML/YML:
.yaml,.yml - JSON:
.json - CMake:
CMakeLists.txt - Make:
Makefile
# Check only changed files (default)
python3 scripts/check_spdx_headers.py --base origin/main
# Check all files in repository
python3 scripts/check_spdx_headers.py --all-files
# Enable debug mode
python3 scripts/check_spdx_headers.py --base origin/main --debug
# Specify custom year
python3 scripts/check_spdx_headers.py --base origin/main --year 2024
# Check only files with specific copyright holder
python3 scripts/check_spdx_headers.py --base origin/main --holder '*UnionTech*'
# Check with exact holder match
python3 scripts/check_spdx_headers.py --base origin/main --holder 'Microsoft Corporation'
# Combine holder filtering with debug mode
python3 scripts/check_spdx_headers.py --all-files --debug --holder '*Software*'
# Combine options
python3 scripts/check_spdx_headers.py --all-files --debug --exclude 'vendor/**' 'node_modules/**'// SPDX-FileCopyrightText: 2026 Your Company Name
// SPDX-License-Identifier: GPL-3.0-or-later# SPDX-FileCopyrightText: 2026 Your Company Name
# SPDX-License-Identifier: GPL-3.0-or-later// SPDX-FileCopyrightText: 2023-2026 Your Company Name
// SPDX-License-Identifier: GPL-3.0-or-laterWhen validation fails, you'll see clear error messages:
[file.py] New files must use a single year (no range) in the SPDX header.
新增文件的 SPDX 版权头必须只包含当前年份,不能使用年份范围。
[oldfile.py] File predates current year; update SPDX header to use a year range 2023-2026.
文件创建年份早于当前年份,请将 SPDX 版权头更新为年份范围 2023-2026。
Run the test suite locally:
pytest tests/ -v --cov=scripts- Python 3.9+
- Python 3.10+
- Python 3.11+
- Python 3.12+
GPL-3.0-or-later