-
Notifications
You must be signed in to change notification settings - Fork 2.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add script for release Nuget validation #2719
Changes from all commits
955c1e7
b9ff980
0234fb3
bfefefe
d6e149f
a03f529
a9b98ad
a269636
2d1db9a
9af1bcd
fffe5b1
1ed144c
775bfe2
a80f0fd
427b7bd
c2cfd9b
9a555ef
3568a69
a407898
e277558
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
parameters: | ||
NugetPath: '' | ||
PlatformsSupported: '' | ||
VerifyNugetSigning: '' | ||
|
||
steps: | ||
- task: UsePythonVersion@0 | ||
displayName: 'Use Python' | ||
inputs: | ||
versionSpec: 3.7 | ||
|
||
- task: PythonScript@0 | ||
displayName: 'Validate Nuget' | ||
inputs: | ||
scriptPath: '$(Build.SourcesDirectory)\tools\nuget\validate_nuget.py' | ||
arguments: '--nuget_path ${{parameters.NugetPath}} --platforms_supported ${{parameters.PlatformsSupported}} --verify_nuget_signing ${{parameters.VerifyNugetSigning}}' | ||
workingDirectory: "$(Build.BinariesDirectory)" |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# Licensed under the MIT License. | ||
|
||
import argparse | ||
import sys | ||
import os | ||
import zipfile # Available Python 3.2 or higher | ||
import glob | ||
|
||
def parse_arguments(): | ||
parser = argparse.ArgumentParser(description="ONNX Runtime create nuget spec script", | ||
usage='') | ||
# Main arguments | ||
parser.add_argument("--nuget_path", required=True, help="Path containing the Nuget to be validated. Must only contain only one Nuget within this.") | ||
parser.add_argument("--platforms_supported", required=True, help="Comma separated list (no space). Ex: linux-x64,win-x86,osx-x64") | ||
parser.add_argument("--verify_nuget_signing", required=True, help="Flag inidicating if Nuget package signing is to be verified. Only accepets 'true' or 'false'") | ||
|
||
return parser.parse_args() | ||
|
||
def check_exists(path): | ||
return os.path.exists(path) | ||
|
||
def is_windows(): | ||
return sys.platform.startswith("win") | ||
|
||
def check_if_dlls_are_present(platforms_supported, zip_file): | ||
platforms = platforms_supported.strip().split(",") | ||
for platform in platforms: | ||
if platform.startswith("win"): | ||
path = "runtimes/" + platform + "/native/onnxruntime.dll" | ||
print('Checking path: ' + path) | ||
if (not path in zip_file.namelist()): | ||
print("onnxruntime.dll not found for " + platform) | ||
print(zip_file.namelist()) | ||
raise Exception("onnxruntime.dll not found for " + platform) | ||
|
||
elif platform.startswith("linux"): | ||
path = "runtimes/" + platform + "/native/libonnxruntime.so" | ||
print('Checking path: ' + path) | ||
if (not path in zip_file.namelist()): | ||
print("libonnxruntime.so not found for " + platform) | ||
raise Exception("libonnxruntime.so not found for " + platform) | ||
|
||
elif platform.startswith("osx"): | ||
path = "runtimes/" + platform + "/native/libonnxruntime.dylib" | ||
print('Checking path: ' + path) | ||
if (not path in zip_file.namelist()): | ||
print("libonnxruntime.dylib not found for " + platform) | ||
raise Exception("libonnxruntime.dylib not found for " + platform) | ||
|
||
else: | ||
raise Exception("Unsupported platform: " + platform) | ||
|
||
def check_if_nuget_is_signed(nuget_path): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This step might be confusing as we have a standalone step in the pipeline that does the signing and if that step fails and the pipeline stops, this verification seems redundant. But during one of the releases, we had an accidental scenario wherein the nuget that was composed in the BinariesDirectory was copied over to the ArtifactStagingDirectory and then the nuget in the BinariesDirectory was signed successfully (but this is of no use as we rely on the one in the ArtifactStagingDirectory). This specific logic added makes sure the Nuget in the ArtifactStagingDirectory is signed (the path fed to this file must be correct, of course) |
||
code_sign_summary_file = glob.glob(os.path.join(nuget_path, '*.md')) | ||
if (len(code_sign_summary_file) != 1): | ||
print('CodeSignSummary files found in path: ') | ||
print(code_sign_summary_file) | ||
raise Exception('No CodeSignSummary files / more than one CodeSignSummary files found in the given path.') | ||
|
||
print('CodeSignSummary file: ' + code_sign_summary_file[0]) | ||
|
||
with open(code_sign_summary_file[0]) as f: | ||
contents = f.read() | ||
return "Pass" in contents | ||
|
||
return False | ||
|
||
def main(): | ||
args = parse_arguments() | ||
|
||
files = os.listdir(args.nuget_path) | ||
nuget_packages_found_in_path = [i for i in files if i.endswith('.nupkg')] | ||
if (len(nuget_packages_found_in_path) != 1): | ||
print('Nuget packages found in path: ') | ||
print(nuget_packages_found_in_path) | ||
raise Exception('No Nuget packages / more than one Nuget packages found in the given path.') | ||
|
||
nuget_file_name = nuget_packages_found_in_path[0] | ||
full_nuget_path = os.path.join(args.nuget_path, nuget_file_name) | ||
|
||
exit_code = 0 | ||
|
||
nupkg_copy_name = "NugetCopy" + ".nupkg" | ||
zip_copy_name = "NugetCopy" + ".zip" | ||
zip_file = None | ||
|
||
# Remove any residual files | ||
if check_exists(nupkg_copy_name): | ||
os.remove(nupkg_copy_name) | ||
|
||
if check_exists(zip_copy_name): | ||
os.remove(zip_copy_name) | ||
|
||
# Do all validations here | ||
try: | ||
if not is_windows(): | ||
raise Exception('Nuget validation is currently supported only on Windows') | ||
|
||
# Make a copy of the Nuget package | ||
print('Making a copy of the Nuget and extracting its contents') | ||
os.system("copy " + full_nuget_path + " " + nupkg_copy_name) | ||
|
||
# Convert nupkg to zip | ||
os.rename(nupkg_copy_name, zip_copy_name) | ||
zip_file = zipfile.ZipFile(zip_copy_name) | ||
|
||
# Check if the relevant dlls are present in the Nuget/Zip | ||
print('Checking if the Nuget contains relevant dlls') | ||
check_if_dlls_are_present(args.platforms_supported, zip_file) | ||
|
||
# Check if the Nuget has been signed | ||
if (args.verify_nuget_signing != 'true' and args.verify_nuget_signing != 'false'): | ||
raise Exception('Parameter verify_nuget_signing accepts only true or false as an argument'); | ||
|
||
if (args.verify_nuget_signing == 'true'): | ||
print('Verifying if Nuget has been signed') | ||
if(not check_if_nuget_is_signed(args.nuget_path)): | ||
print('Nuget signing verification failed') | ||
raise Exception('Nuget signing verification failed') | ||
|
||
except: | ||
exit_code = 1 | ||
|
||
finally: | ||
print('Cleaning up after Nuget validation') | ||
|
||
if zip_file is not None: | ||
zip_file.close() | ||
|
||
if check_exists(zip_copy_name): | ||
os.remove(zip_copy_name) | ||
|
||
if exit_code == 0: | ||
print('Nuget validation was successful') | ||
else: | ||
raise Exception('Nuget validation was unsuccessful') | ||
|
||
if __name__ == "__main__": | ||
sys.exit(main()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For some reason, I am able to manually trigger a job only after adding this line. I don't quite know how it was working previously without this.