AutoRelease + Header Checker Upgrades (#482)

* Initial version where all deps are pylibs
* mechanism for undoing an autorelease
* misc refactor touchups
* +mechanism to baseline older commit into detached HEAD tag
* decouple kernel check configs + misc refactor improvements
* improved compatibility with git action
* Get pushes working in git action with release
* Fix header-check issue when same deletion occurs in parallel
* Add help message in case check fails
* Address PR feedback
This commit is contained in:
David Chalco
2020-12-20 17:03:37 -08:00
committed by GitHub
parent 1f9389c7c4
commit 0527a2a02a
9 changed files with 864 additions and 675 deletions

View File

@@ -1,483 +0,0 @@
#!/usr/bin/env python3
import os, sys, re
from argparse import ArgumentParser
from difflib import unified_diff
from json import load
def dprint(msg):
print('[DEBUG]: %s' % str(msg))
class HeaderChecker:
def __init__(self, header, padding=1000, ignored_files=[], ignored_ext=[], ignored_patterns=[]):
self.padding = padding
self.header = header
self.ignorePatternList = ignored_patterns.copy()
self.ignoreFileList = ignored_files.copy()
self.ignoreExtList = ignored_ext.copy()
def checkJSONList(self, path_json):
'''
This is particularly useful when ingesting output from other programs, like git actions
'''
assert os.path.exists(path_json), 'No such file: ' + path_json
# Get list of files to check from JSON file
with open(path_json) as file_json:
file_checklist = load(file_json)
assert isinstance(file_checklist, list), 'Expected list for singular JSON List entry'
# Accrue how how files fail the check
n_failed = 0
for path_file in file_checklist:
assert isinstance(path_file, str), 'Unexpected JSON format for ' + path_json
n_failed += not self.isValidFile(path_file)
return n_failed
def isValidFile(self, path):
assert os.path.exists(path), 'No such file: ' + path
# Skip any ignored files
if self.isIgnoredFile(path):
return True
# Skip if entry is a directory.
if os.path.isdir(path):
print('Skipping valid file check on directory path: %s' % path)
return True
# Don't need entire file. Read sufficienly large chunk of file that should contain the header
with open(path, encoding='utf-8', errors='ignore') as file:
chunk = file.read(len(''.join(self.header)) + self.padding)
lines = [('%s\n' % l) for l in chunk.strip().splitlines()][:len(self.header)]
if self.header == lines:
return True
else:
print('File Delta: %s' % path)
print(*unified_diff(lines[:len(self.header)], self.header))
return False
def ignoreExtension(self, *args):
for ext in args:
self.ignoreExtList.append(ext)
def ignoreFile(self, *args):
for f in args:
self.ignoreFileList.append(f)
def ignorePattern(self, *args):
for p in args:
self.ignorePatternList.append(re.compile(p))
def isIgnoredFile(self, path):
'''
There are multiple ways a file can be ignored. This is a catch all
'''
assert os.path.exists(path), 'No such file: ' + path
# Try simpler checks first
filename = os.path.split(path)[-1]
extension = os.path.splitext(filename)[-1]
if extension in self.ignoreExtList or filename in self.ignoreFileList:
return True
# Then iterate against regex patterns. In future consider Trie
for pattern in self.ignorePatternList:
if pattern.match(path):
return True
return False
def configArgParser():
parser = ArgumentParser(description='FreeRTOS file header checker. We expect a consistent header across all '
'first party files. The header includes current version number, copyright, '
'and FreeRTOS license.')
parser.add_argument('files_checked',
nargs = '+',
metavar = 'FILE_LIST',
help = 'Space separated list of files to check.')
parser.add_argument('-k', '--kernel',
default = False,
action = 'store_true',
help = 'Compare with kernel file header. It has different versioning.')
parser.add_argument('-j', '--json',
default = False,
action = 'store_true',
help = 'Treat arguments json files that store a list of files to check.')
return parser
#--------------------------------------------------------------------------------------------------
# CONFIG
#--------------------------------------------------------------------------------------------------
FREERTOS_IGNORED_EXTENSIONS = [
'.1',
'.ASM',
'.C',
'.DSW',
'.G_C',
'.H',
'.Hbp',
'.IDE',
'.LIB',
'.Opt',
'.PC',
'.PRM',
'.TXT',
'.URL',
'.UVL',
'.Uv2',
'.a',
'.ac',
'.am',
'.atsln',
'.atstart',
'.atsuo',
'.bash',
'.bat',
'.bbl',
'.bit',
'.board',
'.bsb',
'.bsdl',
'.bts',
'.ccxml',
'.cdkproj',
'.cdkws',
'.cfg',
'.cgp',
'.cmake',
'.cmd',
'.config',
'.cpp',
'.cproj',
'.crun',
'.css',
'.csv',
'.custom_argvars',
'.cxx',
'.cydwr',
'.cyprj',
'.cysch',
'.dat',
'.datas',
'.db',
'.dbgdt',
'.dep',
'.dni',
'.dnx',
'.doc',
'.dox',
'.doxygen',
'.ds',
'.dsk',
'.dtd',
'.dts',
'.elf',
'.env_conf',
'.ewd',
'.ewp',
'.ewt',
'.eww',
'.exe',
'.filters',
'.flash',
'.fmt',
'.ftl',
'.gdb',
'.gif',
'.gise',
'.gld',
'.gpdsc',
'.gui',
'.h_from_toolchain',
'.hdf',
'.hdp',
'.hex',
'.hist',
'.history',
'.hsf',
'.htm',
'.html',
'.hwc',
'.hwl',
'.hwp',
'.hws',
'.hzp',
'.hzs',
'.i',
'.icf',
'.ide',
'.idx',
'.in',
'.inc',
'.include',
'.index',
'.inf',
'.ini',
'.init',
'.ipcf',
'.ise',
'.jlink',
'.json',
'.la',
'.launch',
'.lcf',
'.lds',
'.lib',
'.lk1',
'.lkr',
'.lm',
'.lo',
'.lock',
'.lsl',
'.lst',
'.m4',
'.mac',
'.make',
'.map',
'.mbt',
'.mcp',
'.mcpar',
'.mcs',
'.mcw',
'.md',
'.mdm',
'.mem',
'.mhs',
'.mk',
'.mk1',
'.mmi',
'.mrt',
'.mss',
'.mtpj',
'.nav',
'.ntrc_log',
'.opa',
'.opb',
'.opc',
'.opl',
'.opt',
'.opv',
'.out',
'.pack',
'.par',
'.patch',
'.pbd',
'.pdsc',
'.pe',
'.pem',
'.pgs',
'.pl',
'.plg',
'.png',
'.prc',
'.pref',
'.prefs',
'.prj',
'.properties',
'.ps1',
'.ptf',
'.r79',
'.rapp',
'.rc',
'.reggroups',
'.reglist',
'.resc',
'.resources',
'.rom',
'.rprj',
'.s79',
'.s82',
'.s90',
'.sc',
'.scf',
'.scfg',
'.script',
'.sct',
'.scvd',
'.session',
'.sfr',
'.sh',
'.shtml',
'.sig',
'.sln',
'.spec',
'.stf',
'.stg',
'.suo',
'.sup',
'.svg',
'.tags',
'.tcl',
'.tdt',
'.template',
'.tgt',
'.tps',
'.tra',
'.tree',
'.tws',
'.txt',
'.ucf',
'.url',
'.user',
'.ut',
'.uvmpw',
'.uvopt',
'.uvoptx',
'.uvproj',
'.uvprojx',
'.vcproj',
'.vcxproj',
'.version',
'.webserver',
'.wpj',
'.wsdt',
'.wsp',
'.wspos',
'.wsx',
'.x',
'.xbcd',
'.xcl',
'.xise',
'.xml',
'.xmp',
'.xmsgs',
'.xsl',
'.yml',
'.md',
'.zip'
]
FREERTOS_IGNORED_PATTERNS = [
r'.*\.git.*',
r'.*mbedtls_config\.h.*',
r'.*mbedtls_config\.h.*',
r'.*CMSIS.*',
r'.*/makefile',
r'.*/Makefile',
r'.*/trcConfig\.h.*',
r'.*/trcConfig\.c.*',
r'.*/trcSnapshotConfig\.h.*',
]
FREERTOS_HEADER = [
'/*\n',
' * FreeRTOS V202012.00\n',
' * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n',
' *\n',
' * Permission is hereby granted, free of charge, to any person obtaining a copy of\n',
' * this software and associated documentation files (the "Software"), to deal in\n',
' * the Software without restriction, including without limitation the rights to\n',
' * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n',
' * the Software, and to permit persons to whom the Software is furnished to do so,\n',
' * subject to the following conditions:\n',
' *\n',
' * The above copyright notice and this permission notice shall be included in all\n',
' * copies or substantial portions of the Software.\n',
' *\n',
' * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n',
' * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n',
' * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n',
' * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n',
' * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n',
' * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n',
' *\n',
' * https://www.FreeRTOS.org\n',
' * https://github.com/FreeRTOS\n',
' *\n',
' */\n',
]
KERNEL_IGNORED_EXTENSIONS = [
'.yml',
'.css',
'.idx',
'.md',
'.url',
'.sty',
'.0-rc2',
'.s82',
'.js',
'.out',
'.pack',
'.2',
'.1-kernel-only',
'.0-kernel-only',
'.0-rc1',
'.readme',
'.tex',
'.png',
'.bat',
'.sh'
]
KERNEL_IGNORED_PATTERNS = [r'.*\.git.*']
KERNEL_HEADER = [
'/*\n',
' * FreeRTOS Kernel V10.4.2\n',
' * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n',
' *\n',
' * Permission is hereby granted, free of charge, to any person obtaining a copy of\n',
' * this software and associated documentation files (the "Software"), to deal in\n',
' * the Software without restriction, including without limitation the rights to\n',
' * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n',
' * the Software, and to permit persons to whom the Software is furnished to do so,\n',
' * subject to the following conditions:\n',
' *\n',
' * The above copyright notice and this permission notice shall be included in all\n',
' * copies or substantial portions of the Software.\n',
' *\n',
' * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n',
' * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n',
' * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n',
' * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n',
' * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n',
' * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n',
' *\n',
' * https://www.FreeRTOS.org\n',
' * https://github.com/FreeRTOS\n',
' *\n',
' */\n',
]
#--------------------------------------------------------------------------------------------------
# MAIN
#--------------------------------------------------------------------------------------------------
def main():
parser = configArgParser()
args = parser.parse_args()
# Configure checks
if args.kernel:
checker = HeaderChecker(KERNEL_HEADER)
checker.ignoreExtension(*KERNEL_IGNORED_EXTENSIONS)
checker.ignorePattern(*KERNEL_IGNORED_PATTERNS)
else:
checker = HeaderChecker(FREERTOS_HEADER)
checker.ignoreExtension(*FREERTOS_IGNORED_EXTENSIONS)
checker.ignorePattern(*FREERTOS_IGNORED_PATTERNS)
checker.ignoreFile(os.path.split(__file__)[-1])
# Check all input files
print()
n_failed = 0
for path in args.files_checked:
if args.json:
n_failed += checker.checkJSONList(path)
else:
n_failed += not checker.isValidFile(path)
return n_failed
if __name__ == '__main__':
exit(main())

133
.github/scripts/common/header_checker.py vendored Executable file
View File

@@ -0,0 +1,133 @@
#!/usr/bin/env python3
import os, sys, re
from argparse import ArgumentParser
from difflib import unified_diff
from json import load
def dprint(msg):
print('[DEBUG]: %s' % str(msg))
class HeaderChecker:
def __init__(self, header, padding=1000, ignored_files=[], ignored_ext=[], ignored_patterns=[]):
self.padding = padding
self.header = header
self.ignorePatternList = ignored_patterns.copy()
self.ignoreFileList = ignored_files.copy()
self.ignoreExtList = ignored_ext.copy()
def checkJSONList(self, path_json):
'''
This is particularly useful when ingesting output from other programs, like git actions
'''
assert os.path.exists(path_json), 'No such file: ' + path_json
# Get list of files to check from JSON file
with open(path_json) as file_json:
file_checklist = load(file_json)
assert isinstance(file_checklist, list), 'Expected list for singular JSON List entry'
# Accrue how how files fail the check
n_failed = 0
for path_file in file_checklist:
assert isinstance(path_file, str), 'Unexpected JSON format for ' + path_json
if os.path.exists(path_file) and not self.isValidFile(path_file):
n_failed += 1
return n_failed
def isValidFile(self, path):
assert os.path.exists(path), 'No such file: ' + path
print('-------------------------------------------------------------------------------------')
print('Checking file: %s...' % path, end='')
if self.isIgnoredFile(path) or os.path.isdir(path):
print('SKIP')
print('-------------------------------------------------------------------------------------')
return True
# Don't need entire file. Read sufficiently large chunk of file that should contain the header
with open(path, encoding='utf-8', errors='ignore') as file:
chunk = file.read(len(''.join(self.header)) + self.padding)
lines = [('%s\n' % l) for l in chunk.strip().splitlines()][:len(self.header)]
if self.header == lines:
print('PASS')
print('-------------------------------------------------------------------------------------')
return True
else:
print('FAIL')
print('File Delta: %s' % path)
print(*unified_diff(lines[:len(self.header)], self.header))
print('-------------------------------------------------------------------------------------')
return False
def ignoreExtension(self, *args):
for ext in args:
self.ignoreExtList.append(ext)
def ignoreFile(self, *args):
for f in args:
self.ignoreFileList.append(f)
def ignorePattern(self, *args):
for p in args:
self.ignorePatternList.append(re.compile(p))
def isIgnoredFile(self, path):
'''
There are multiple ways a file can be ignored. This is a catch all
'''
assert os.path.exists(path), 'No such file: ' + path
# Try simpler checks first
filename = os.path.split(path)[-1]
extension = os.path.splitext(filename)[-1]
if extension in self.ignoreExtList or filename in self.ignoreFileList:
return True
# Then iterate against regex patterns. In future consider Trie
for pattern in self.ignorePatternList:
if pattern.match(path):
return True
return False
def showHelp(self, path_config):
print('\n\n'
"Please fix all highlighted diffs or add exceptions to '%s' as necessary.\n"
"Include your changes to '%s' in your PR. Git PR checks source this file from your PR.\n"
"\n"
"The FreeRTOS Header Check ensures all files that contain FreeRTOS Headers are up to date\n"
"with the latest version, copyright, and licensing info."
"\n\n" % (path_config, path_config))
@staticmethod
def configArgParser():
parser = ArgumentParser(description='FreeRTOS file header checker. We expect a consistent header across all '
'first party files. The header includes current version number, copyright, '
'and FreeRTOS license.')
parser.add_argument('files_checked',
nargs = '+',
metavar = 'FILE_LIST',
help = 'Space separated list of files to check.')
parser.add_argument('-j', '--json',
default = False,
action = 'store_true',
help = 'Treat arguments json files that store a list of files to check.')
return parser
def processArgs(self, args):
n_failed = 0
if args.json:
for path in args.files_checked:
n_failed += self.checkJSONList(path)
else:
for path in args.files_checked:
n_failed += not self.isValidFile(path)
return n_failed

313
.github/scripts/core_checker.py vendored Executable file
View File

@@ -0,0 +1,313 @@
#!/usr/bin/env python3
# python >= 3.4
import os
from common.header_checker import HeaderChecker
#--------------------------------------------------------------------------------------------------
# CONFIG
#--------------------------------------------------------------------------------------------------
FREERTOS_IGNORED_EXTENSIONS = [
'.1',
'.ASM',
'.C',
'.DSW',
'.G_C',
'.H',
'.Hbp',
'.IDE',
'.LIB',
'.Opt',
'.PC',
'.PRM',
'.TXT',
'.URL',
'.UVL',
'.Uv2',
'.a',
'.ac',
'.am',
'.atsln',
'.atstart',
'.atsuo',
'.bash',
'.bat',
'.bbl',
'.bit',
'.board',
'.bsb',
'.bsdl',
'.bts',
'.ccxml',
'.cdkproj',
'.cdkws',
'.cfg',
'.cgp',
'.cmake',
'.cmd',
'.config',
'.cpp',
'.cproj',
'.crun',
'.css',
'.csv',
'.custom_argvars',
'.cxx',
'.cydwr',
'.cyprj',
'.cysch',
'.dat',
'.datas',
'.db',
'.dbgdt',
'.dep',
'.dni',
'.dnx',
'.doc',
'.dox',
'.doxygen',
'.ds',
'.dsk',
'.dtd',
'.dts',
'.elf',
'.env_conf',
'.ewd',
'.ewp',
'.ewt',
'.eww',
'.exe',
'.filters',
'.flash',
'.fmt',
'.ftl',
'.gdb',
'.gif',
'.gise',
'.gld',
'.gpdsc',
'.gui',
'.h_from_toolchain',
'.hdf',
'.hdp',
'.hex',
'.hist',
'.history',
'.hsf',
'.htm',
'.html',
'.hwc',
'.hwl',
'.hwp',
'.hws',
'.hzp',
'.hzs',
'.i',
'.icf',
'.ide',
'.idx',
'.in',
'.inc',
'.include',
'.index',
'.inf',
'.ini',
'.init',
'.ipcf',
'.ise',
'.jlink',
'.json',
'.la',
'.launch',
'.lcf',
'.lds',
'.lib',
'.lk1',
'.lkr',
'.lm',
'.lo',
'.lock',
'.lsl',
'.lst',
'.m4',
'.mac',
'.make',
'.map',
'.mbt',
'.mcp',
'.mcpar',
'.mcs',
'.mcw',
'.md',
'.mdm',
'.mem',
'.mhs',
'.mk',
'.mk1',
'.mmi',
'.mrt',
'.mss',
'.mtpj',
'.nav',
'.ntrc_log',
'.opa',
'.opb',
'.opc',
'.opl',
'.opt',
'.opv',
'.out',
'.pack',
'.par',
'.patch',
'.pbd',
'.pdsc',
'.pe',
'.pem',
'.pgs',
'.pl',
'.plg',
'.png',
'.prc',
'.pref',
'.prefs',
'.prj',
'.properties',
'.ps1',
'.ptf',
'.r79',
'.rapp',
'.rc',
'.reggroups',
'.reglist',
'.resc',
'.resources',
'.rom',
'.rprj',
'.s79',
'.s82',
'.s90',
'.sc',
'.scf',
'.scfg',
'.script',
'.sct',
'.scvd',
'.session',
'.sfr',
'.sh',
'.shtml',
'.sig',
'.sln',
'.spec',
'.stf',
'.stg',
'.suo',
'.sup',
'.svg',
'.tags',
'.tcl',
'.tdt',
'.template',
'.tgt',
'.tps',
'.tra',
'.tree',
'.tws',
'.txt',
'.ucf',
'.url',
'.user',
'.ut',
'.uvmpw',
'.uvopt',
'.uvoptx',
'.uvproj',
'.uvprojx',
'.vcproj',
'.vcxproj',
'.version',
'.webserver',
'.wpj',
'.wsdt',
'.wsp',
'.wspos',
'.wsx',
'.x',
'.xbcd',
'.xcl',
'.xise',
'.xml',
'.xmp',
'.xmsgs',
'.xsl',
'.yml',
'.md',
'.zip'
]
FREERTOS_IGNORED_PATTERNS = [
r'.*\.git.*',
r'.*mbedtls_config\.h.*',
r'.*mbedtls_config\.h.*',
r'.*CMSIS.*',
r'.*/makefile',
r'.*/Makefile',
r'.*/trcConfig\.h.*',
r'.*/trcConfig\.c.*',
r'.*/trcSnapshotConfig\.h.*',
]
FREERTOS_IGNORED_FILES = [
'fyi-another-way-to-ignore-file.txt',
'mbedtls_config.h'
]
FREERTOS_HEADER = [
'/*\n',
' * FreeRTOS V202012.00\n',
' * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n',
' *\n',
' * Permission is hereby granted, free of charge, to any person obtaining a copy of\n',
' * this software and associated documentation files (the "Software"), to deal in\n',
' * the Software without restriction, including without limitation the rights to\n',
' * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\n',
' * the Software, and to permit persons to whom the Software is furnished to do so,\n',
' * subject to the following conditions:\n',
' *\n',
' * The above copyright notice and this permission notice shall be included in all\n',
' * copies or substantial portions of the Software.\n',
' *\n',
' * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n',
' * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\n',
' * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\n',
' * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\n',
' * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\n',
' * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n',
' *\n',
' * https://www.FreeRTOS.org\n',
' * https://github.com/FreeRTOS\n',
' *\n',
' */\n',
]
def main():
parser = HeaderChecker.configArgParser()
args = parser.parse_args()
# Configure the checks then run
checker = HeaderChecker(FREERTOS_HEADER)
checker.ignoreExtension(*FREERTOS_IGNORED_EXTENSIONS)
checker.ignorePattern(*FREERTOS_IGNORED_PATTERNS)
checker.ignoreFile(*FREERTOS_IGNORED_FILES)
checker.ignoreFile(os.path.split(__file__)[-1])
rc = checker.processArgs(args)
if rc:
checker.showHelp(__file__)
return rc
if __name__ == '__main__':
exit(main())

View File

@@ -0,0 +1,13 @@
certifi>=2020.12.5
chardet>=3.0.4
Deprecated>=1.2.10
gitdb>=4.0.5
GitPython>=3.1.11
idna>=2.10
PyGithub>=1.54
PyJWT>=1.7.1
PyYAML>=5.3.1
requests>=2.24.0
smmap>=3.0.4
urllib3>=1.25.11
wrapt>=1.12.1

File diff suppressed because it is too large Load Diff

View File

@@ -69,7 +69,7 @@ def ask_yes_no_question(question):
return answer
def list_files_in_a_component(component, afr_path, exclude_dirs=[], ext_filter=['.c', '.h']):
def list_files_in_a_component(component, afr_path, exclude_dirs=[], ext_filter=['.c', '.h'], exclude_hidden=True):
'''
Returns a list of all the files in a component.
'''
@@ -77,19 +77,17 @@ def list_files_in_a_component(component, afr_path, exclude_dirs=[], ext_filter=[
search_path = os.path.join(afr_path, component)
for root, dirs, files in os.walk(search_path, topdown=True):
dirs[:] = [d for d in dirs if d not in exclude_dirs]
# Do not include hidden files and folders.
dirs[:] = [d for d in dirs if not d[0] == '.']
files = [f for f in files if not f[0] == '.']
# Current root is an excluded dir so skip
if root in exclude_dirs:
continue
for f in files:
if ext_filter != None:
ext = '.' + f.split('.')[-1]
if ext in ext_filter:
if exclude_hidden and f[0] == '.':
continue
if (ext_filter is None
or ext_filter is not None and os.path.splitext(f)[-1] in ext_filter):
list_of_files.append(os.path.join(os.path.relpath(root, afr_path), f))
else:
list_of_files.append(os.path.join(os.path.relpath(root, afr_path), f))
return list_of_files
@@ -104,6 +102,8 @@ def extract_version_number_from_file(file_path):
# Is it a kernel file?
if match is None:
match = re.search('\s*\*\s*(FreeRTOS Kernel.*V(.*))', content, re.MULTILINE)
if match is None:
match = re.search('\s*\*\s*(FreeRTOS V(.*\..*))', content, re.MULTILINE)
# Is it s FreeRTOS+TCP file?
if match is None:
match = re.search('\s*\*\s*(FreeRTOS\+TCP.*V(.*))', content, re.MULTILINE)
@@ -194,7 +194,6 @@ def process_components(root_dir, components, exclude_dirs=[]):
update_version_number_in_a_component(c, root_dir, exclude_dirs=exclude_dirs)
def update_freertos_version_macros(path_macrofile, major, minor, build):
print('\nUpdating preprocessor version macros...')
with open(path_macrofile, encoding='utf-8', errors='ignore', newline='') as macro_file:
macro_file_content = macro_file.read()
match_version = re.search(r'(^.*#define *tskKERNEL_VERSION_NUMBER *(".*")$)', macro_file_content, re.MULTILINE)
@@ -222,12 +221,10 @@ def update_freertos_version_macros(path_macrofile, major, minor, build):
with open(path_macrofile, 'w', newline='') as macro_file:
macro_file.write(macro_file_content)
print('Done. Replaced "%s" --> "V%s.%s.%s".' % (old_version_number, major, minor, build))
def update_version_number_in_freertos_component(component, root_dir, old_version_prefix_list, new_version, verbose=False):
def update_version_number_in_freertos_component(component, root_dir, old_version_prefix_list, new_version,
verbose=False, exclude_hidden=True):
assert isinstance(old_version_prefix_list, list), 'Expected a list for arg(old_version_prefix_list)'
print('Updating "%s"...' % component)
component_files = list_files_in_a_component(component, root_dir, ext_filter=None)
component_files = list_files_in_a_component(component, root_dir, ext_filter=None, exclude_hidden=exclude_hidden)
version_numbers = defaultdict(list)
n_updated = 0
@@ -257,7 +254,6 @@ def update_version_number_in_freertos_component(component, root_dir, old_version
update_version_number_in_files(files_using_old_version, old_version_string, new_version_string)
n_updated += len(files_using_old_version)
print('Updated "%d" files.' % n_updated)
return n_updated
def process_freertos_components(root_dir, components, old_version, new_version, verbose=False):

51
.github/workflows/auto-release.yml vendored Normal file
View File

@@ -0,0 +1,51 @@
name: Auto-Release
on:
workflow_dispatch:
inputs:
commit_id:
description: 'Commit ID'
required: true
default: 'HEAD'
version_number:
description: 'Version Number (Ex. 202000.00)'
required: true
jobs:
auto-release:
name: Auto Release
runs-on: ubuntu-latest
steps:
- name: Tool Setup
uses: actions/setup-python@v2
with:
python-version: 3.8.5
architecture: x64
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Source the release tools from FreeRTOS/FreeRTOS
- name: Checkout FreeRTOS Release Tools
uses: actions/checkout@v2
with:
path: tools
# Simpler git auth if we use checkout action and forward the repo to release script
- name: Checkout FreeRTOS
uses: actions/checkout@v2
with:
path: local_core
fetch-depth: 0
- name: Release
run: |
# Configure repo for push
git config --global user.name ${{ github.actor }}
git config --global user.email ${{ github.actor }}@users.noreply.github.com
# Run the release script
pip install -r ./tools/.github/scripts/release-requirements.txt
./tools/.github/scripts/release.py FreeRTOS --core-repo-path=local_core --core-commit=${{ github.event.inputs.commit_id }} --new-core-version=${{ github.event.inputs.version_number }}
exit $?
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,10 +1,10 @@
name: FreeRTOS-Header-Checker
name: Core-Checker
on: [pull_request]
jobs:
header-checker:
name: File Header Checks
core-checker:
name: FreeRTOS Core Checks
runs-on: ubuntu-latest
steps:
# Install python 3
@@ -40,6 +40,7 @@ jobs:
- name: Check File Headers
run: |
cd inspect
../tools/.github/scripts/check-header.py --json ${HOME}/files_modified.json ${HOME}/files_added.json ${HOME}/files_renamed.json
export PYTHONPATH=tools/.github/scripts:${PYTHONPATH}
.github/scripts/core_checker.py --json ${HOME}/files_modified.json ${HOME}/files_added.json ${HOME}/files_renamed.json
exit $?

View File

@@ -1,62 +0,0 @@
name: FreeRTOS-Release-Packager
on:
workflow_dispatch:
inputs:
commit_id:
description: 'Commit ID'
required: true
version_number:
description: 'Version Number (Ex. 10.4.1)'
required: true
default: '10.4.1'
jobs:
release-packager:
name: Release Packager
runs-on: ubuntu-latest
steps:
# Need a separate copy to fetch packing tools, as source FreeRTOS dir will be pruned and operated on
- name: Checkout FreeRTOS Tools
uses: actions/checkout@v2
with:
ref: master
path: tools
# Setup packing tools
- name: Tool Setup
uses: actions/setup-python@v2
with:
python-version: 3.8.5
architecture: x64
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Packaging
- name: Packaging
run: python tools/.github/scripts/freertos_zipper.py --freertos-commit ${{ github.event.inputs.commit_id }} --zip-version ${{ github.event.inputs.version_number }}
# Create release endpoint
- name: Create Release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: V${{ github.event.inputs.version_number }}
release_name: FreeRTOS Release V${{ github.event.inputs.version_number }}
draft: false
prerelease: false
commitish: ${{ github.event.inputs.commit_id }}
# Upload release assets the recently created endpoint
- name: Upload Release
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./FreeRTOSv${{ github.event.inputs.version_number }}.zip
asset_name: FreeRTOSv${{ github.event.inputs.version_number }}.zip
asset_content_type: application/zip