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
1 change: 1 addition & 0 deletions release_changes/202507141540.change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ci-license: Check for current year in the license job
3 changes: 2 additions & 1 deletion tools/ci/pipeline-baseline-fri.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ license:
tags:
- iotmsw-amd64
script:
- scancode -l --ignore "**/*.tmp/**" --json-pp scancode_report.json $PWD/..
- scancode -lc --ignore "**/*.tmp/**" --json-pp scancode_report.json $PWD/..
- jsonschema -i scancode_report.json $PWD/tools/ci/license/license.schema
- python3 ${PWD}/tools/scripts/copyright_date_check.py
artifacts:
paths:
- scancode_report.json
Expand Down
65 changes: 65 additions & 0 deletions tools/scripts/copyright_date_check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2025 Arm Limited and/or its affiliates
# <[email protected]>
# SPDX-License-Identifier: MIT

from datetime import datetime, timezone
import json
import pathlib
import os
import subprocess
import sys

HOLDER = "Arm"
CURRENT_YEAR = str(datetime.now(timezone.utc).year)


# Ensures all modified files with Arm copyright have the current year;
# lists the paths of files that need updating
def main():
outdated_year_files = []
report = json.loads(pathlib.Path("scancode_report.json").read_text())
repo_root = pathlib.Path(os.getcwd()).resolve()
path_prefix = f"{repo_root.parent.name}/{repo_root.name}/"

# Builds a dictionary of all files and their corresponding copyright
all_copyrights = {}
for file in report.get("files", []):
scanned_path = file.get("path", "")
if not scanned_path.startswith(path_prefix):
continue
relative_path = scanned_path[slice(len(path_prefix), None)]
all_copyrights[relative_path] = [
cp["value"] for cp in file.get("copyrights", [])
]

# Determine what files have been modified by looking at the commit range
base = os.getenv("CI_MERGE_REQUEST_DIFF_BASE_SHA") or "HEAD^"
head = os.getenv("CI_COMMIT_SHA") or "HEAD"
changed = set(
subprocess.check_output(
["git", "diff", "--name-only", f"{base}...{head}"], text=True
).splitlines()
)

for relative_path in changed:
file_copyrights = all_copyrights.get(relative_path, [])
# If a file doesn't have a copyright, or it is correctly formatted, skip it
if (not file_copyrights) or (
any(HOLDER in cp and CURRENT_YEAR in cp for cp in file_copyrights)
):
continue
if any(HOLDER in cp for cp in file_copyrights):
outdated_year_files.append(relative_path)

if outdated_year_files:
print(
"Please update the copyright year to",
CURRENT_YEAR,
"in the following files:",
)
print("\n".join(f" - {p}" for p in outdated_year_files))
sys.exit(1)


if __name__ == "__main__":
main()