11"""
2- NGO release script
3- - Update changelogs + validation exception file based on manifest version
2+ This python script makes the NGO package release ready. What it does is:
3+ 1) Update changelogs
4+ 2) Update validation exception file based on manifest version
5+
6+ Note that this script NEEDS TO BE RUN FROM THE ROOT of the project.
47"""
58#!/usr/bin/env python3
69import datetime
710import json
811import os
912import re
13+ import subprocess
14+ import platform
1015
1116package_name = 'com.unity.netcode.gameobjects'
1217
1318def update_changelog (new_version ):
19+ """
20+ Cleans the [Unreleased] section of the changelog by removing empty subsections,
21+ then replaces the '[Unreleased]' tag with the new version and release date.
22+ """
23+
1424 changelog_entry = f'## [{ new_version } ] - { datetime .date .today ().isoformat ()} '
1525 changelog_path = f'{ package_name } /CHANGELOG.md'
16- print (changelog_entry )
17-
18- if not os .path .exists (changelog_path ):
19- print (f"Error: CHANGELOG.md file not found at { changelog_path } " )
20- return
26+ print ("Latest CHANGELOG entry will be modified to: " + changelog_entry )
2127
22- with open (changelog_path , 'rb ' ) as f :
28+ with open (changelog_path , 'r' , encoding = 'UTF-8 ' ) as f :
2329 changelog_text = f .read ()
24-
25- changelog_text_decoded = changelog_text .decode ("utf-8" )
26- if '## [Unreleased]' in changelog_text_decoded :
27- # Replace the `Unreleased` section with the new version entry
28- print ("Found `## [Unreleased]` section. Updating it." )
29- changelog_text = re .sub (br'## \[Unreleased\]' , bytes (changelog_entry , 'UTF-8' ), changelog_text )
30- else :
31- # `Unreleased` section does not exist, so prepend the new entry at the top
32- print ("No `## [Unreleased]` section found. Prepending the new entry." )
33- changelog_text = bytes (f"{ changelog_entry } \n \n " , 'UTF-8' ) + changelog_text
34-
35- with open (changelog_path , 'wb' ) as f :
36- f .write (changelog_text )
30+
31+ # This pattern finds a line starting with '###', followed by its newline,
32+ # and then two more lines that contain only whitespace.
33+ # The re.MULTILINE flag allows '^' to match the start of each line.
34+ pattern = re .compile (r"^###.*\n\n\n" , re .MULTILINE )
35+
36+ # Replace every match with an empty string. The goal is to remove empty CHANGELOG subsections.
37+ cleaned_content = pattern .sub ('' , changelog_text )
38+
39+ # Replace the [Unreleased] section with the new version + cleaned subsections
40+ changelog_text = re .sub (r'## \[Unreleased\]' , changelog_entry , cleaned_content )
41+
42+ # Write the changes
43+ with open (changelog_path , 'w' , encoding = 'UTF-8' , newline = '\n ' ) as file :
44+ file .write (changelog_text )
45+
3746
3847def update_validation_exceptions (new_version ):
48+ """
49+ Updates the ValidationExceptions.json file with the new package version.
50+ """
51+
3952 validation_file = f'{ package_name } /ValidationExceptions.json'
53+
54+ # If files do not exist, exit
4055 if not os .path .exists (validation_file ):
4156 return
4257
58+ # Update the PackageVersion in the exceptions
4359 with open (validation_file , 'rb' ) as f :
4460 json_text = f .read ()
4561 data = json .loads (json_text )
@@ -53,26 +69,33 @@ def update_validation_exceptions(new_version):
5369 exception ['PackageVersion' ] = new_version
5470 updated = True
5571
72+ # If no exceptions were updated, we do not need to write the file
5673 if not updated :
5774 return
5875
59- with open (validation_file , "w" , encoding = " UTF-8" ) as json_file :
76+ with open (validation_file , 'w' , encoding = ' UTF-8' , newline = ' \n ' ) as json_file :
6077 json .dump (data , json_file , ensure_ascii = False , indent = 2 )
6178 json_file .write ("\n " ) # Add newline cause Py JSON does not
6279 print (f" updated `{ validation_file } `" )
6380
6481
6582def get_manifest_json_version (filename ):
83+ """
84+ Reads the package.json file and returns the version specified in it.
85+ """
6686 with open (filename , 'rb' ) as f :
6787 json_text = f .read ()
6888 data = json .loads (json_text )
6989
7090 return data ['version' ]
7191
92+
7293if __name__ == '__main__' :
73- print (f"Current working directory: { os .getcwd ()} " )
7494 manifest_path = f'{ package_name } /package.json'
75- version = get_manifest_json_version (manifest_path )
76- update_validation_exceptions (version )
95+ package_version = get_manifest_json_version (manifest_path )
7796
78- update_changelog (version )
97+ # Update the ValidationExceptions.json file
98+ # with the new package version OR remove it if not a release branch
99+ update_validation_exceptions (package_version )
100+ # Clean the CHANGELOG and add latest entry
101+ update_changelog (package_version )
0 commit comments