Skip to content

Commit 01cd080

Browse files
committed
include licencing is kept up-to-date
1 parent f87d5a7 commit 01cd080

2 files changed

Lines changed: 163 additions & 0 deletions

File tree

.github/workflows/check_licence.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
import os
2+
import requests
3+
import base64
4+
from datetime import datetime
5+
6+
# GitHub API endpoint to list repositories in an organisation
7+
REPOS_URL = "https://api.github.com/orgs/{org}/repos"
8+
9+
# GitHub API endpoint to get the contents of a file in a repository
10+
FILE_URL = "https://api.github.com/repos/{org}/{repo}/contents/{path}"
11+
12+
# GitHub API endpoint to create a file in a repository
13+
CREATE_URL = "https://api.github.com/repos/{org}/{repo}/contents/{path}"
14+
15+
# GitHub API endpoint to delete a file in a repository
16+
DELETE_URL = "https://api.github.com/repos/{org}/{repo}/contents/{path}"
17+
18+
# GitHub token for authentication
19+
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
20+
21+
# Organisation name
22+
ORG_NAME = os.getenv("ORG_NAME")
23+
24+
# Copyright owner name
25+
COPYRIGHT_OWNER = os.getenv("COPYRIGHT_OWNER")
26+
27+
# Current year
28+
CURRENT_YEAR = datetime.now().year
29+
30+
# Headers for GitHub API requests
31+
HEADERS = {
32+
"Authorization": f"token {GITHUB_TOKEN}",
33+
"Accept": "application/vnd.github.v3+json"
34+
}
35+
36+
# URL to fetch the Apache 2.0 licence text
37+
APACHE_LICENCE_URL = "https://www.apache.org/licenses/LICENSE-2.0.txt"
38+
39+
def get_repositories(org):
40+
response = requests.get(REPOS_URL.format(org=org), headers=HEADERS)
41+
response.raise_for_status()
42+
return response.json()
43+
44+
def get_file_contents(org, repo, path):
45+
response = requests.get(FILE_URL.format(org=org, repo=repo, path=path), headers=HEADERS)
46+
if response.status_code == 404:
47+
return None
48+
response.raise_for_status()
49+
return response.json()
50+
51+
def create_file(org, repo, path, content):
52+
data = {
53+
"message": "Add Apache 2.0 licence",
54+
"content": content
55+
}
56+
response = requests.put(CREATE_URL.format(org=org, repo=repo, path=path), headers=HEADERS, json=data)
57+
response.raise_for_status()
58+
59+
def update_file(org, repo, path, content, sha):
60+
data = {
61+
"message": "Update licence with current year and copyright owner",
62+
"content": content,
63+
"sha": sha
64+
}
65+
response = requests.put(CREATE_URL.format(org=org, repo=repo, path=path), headers=HEADERS, json=data)
66+
response.raise_for_status()
67+
68+
def delete_file(org, repo, path, sha):
69+
data = {
70+
"message": "Rename LICENSE to LICENCE",
71+
"sha": sha
72+
}
73+
response = requests.delete(DELETE_URL.format(org=org, repo=repo, path=path), headers=HEADERS, json=data)
74+
response.raise_for_status()
75+
76+
def fetch_apache_licence():
77+
response = requests.get(APACHE_LICENCE_URL)
78+
response.raise_for_status()
79+
return response.text
80+
81+
def main():
82+
repos = get_repositories(ORG_NAME)
83+
apache_licence_text = fetch_apache_licence()
84+
85+
for repo in repos:
86+
repo_name = repo["name"]
87+
licence_file = get_file_contents(ORG_NAME, repo_name, "LICENCE")
88+
license_file = get_file_contents(ORG_NAME, repo_name, "LICENSE")
89+
90+
if licence_file is None and license_file is None:
91+
print(f"No LICENCE or LICENSE file found in {repo_name}, adding Apache 2.0 licence")
92+
# Encode the Apache 2.0 licence text to base64
93+
encoded_licence = base64.b64encode(apache_licence_text.encode("utf-8")).decode("utf-8")
94+
# Create the LICENCE file in the repository
95+
create_file(ORG_NAME, repo_name, "LICENCE", encoded_licence)
96+
continue
97+
98+
if license_file is not None:
99+
# Rename LICENSE to LICENCE
100+
content = license_file["content"]
101+
sha = license_file["sha"]
102+
delete_file(ORG_NAME, repo_name, "LICENSE", sha)
103+
create_file(ORG_NAME, repo_name, "LICENCE", content)
104+
print(f"Renamed LICENSE to LICENCE in {repo_name}")
105+
106+
content = licence_file["content"]
107+
sha = licence_file["sha"]
108+
decoded_content = base64.b64decode(content).decode("utf-8")
109+
110+
# Check if the year is not the current year and update it
111+
if f"{CURRENT_YEAR} {COPYRIGHT_OWNER}" not in decoded_content:
112+
# Update the licence content with the current year and copyright owner
113+
updated_content = decoded_content.replace(
114+
"[yyyy] [name of copyright owner]",
115+
f"{CURRENT_YEAR} {COPYRIGHT_OWNER}"
116+
)
117+
else:
118+
updated_content = decoded_content
119+
120+
# Encode the updated content back to base64
121+
encoded_content = base64.b64encode(updated_content.encode("utf-8")).decode("utf-8")
122+
123+
# Update the file in the repository
124+
update_file(ORG_NAME, repo_name, "LICENCE", encoded_content, sha)
125+
print(f"Updated LICENCE file in {repo_name}")
126+
127+
if __name__ == "__main__":
128+
main()
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: Ensure Licence Correctness
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
workflow_dispatch:
8+
schedule:
9+
- cron: '0 0 1 1 *' # Runs at 00:00 UTC on January 1st
10+
11+
jobs:
12+
check-licence:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v2
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v2
21+
with:
22+
python-version: '3.x'
23+
24+
- name: Install dependencies
25+
run: |
26+
python -m pip install --upgrade pip
27+
pip install requests
28+
29+
- name: Check and update licence
30+
env:
31+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32+
ORG_NAME: STRONGAYA
33+
COPYRIGHT_OWNER: STRONGAYA
34+
run: |
35+
python .github/workflows/check_licence.py

0 commit comments

Comments
 (0)