Skip to content

Commit

Permalink
Add GH action for verifying manifest.yml (#32)
Browse files Browse the repository at this point in the history
Add a GitHub Action to enable repositories like aws/aws-iot-embedded-device-c-sdk and FreeRTOS/FreeRTOS verify their manifest.yml files to ensure that all required submodule entires are present along with the latest commit ID information
  • Loading branch information
aggarw13 authored Jul 28, 2021
1 parent ae6c154 commit 35c9714
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 3 deletions.
26 changes: 24 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:
with:
path: coreMQTT
test-doxygen-zip-check:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
Expand All @@ -56,7 +56,7 @@ jobs:
libs_parent_dir_path: libraries/standard,libraries/aws
generate_zip: true
test-doxygen-non-zip-check:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v2
Expand Down Expand Up @@ -141,3 +141,25 @@ jobs:
path: ./
exclude-dirs: complexity,formatting
include-file-types: .c,.html
test-manifest-verifier:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup python environment
uses: actions/setup-python@v2
with:
python-version: '3.x'
- name: Checkout the FreeRTOS/FreeRTOS repository for testing action on.
uses: actions/checkout@v2
with:
repository: FreeRTOS/FreeRTOS
ref: '202107.00'
path: FreeRTOS
submodules: recursive
- name: Test manifest verifier
uses: ./manifest-verifier
with:
path: ./FreeRTOS
exclude-submodules: FreeRTOS-Plus/Test/CMock,FreeRTOS/Test/CMock/CMock,FreeRTOS/Test/litani
fail-on-incorrect-version: true

4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@ FreeRTOS libraries.
library documentation. The memory estimates are generated by building the library with the ARM GCC
toolchain.
* **Link Verifier** - Verifies links present in source and Markdown files. Links verified include HTTP
URLs, and - for Markdown files - relative file path links and section anchors.
* **Manifest.yml Verifier** - Verifies that information of `manifest.yml` file matches the state of a repository for the presence of submodules and their commit IDs.

URLs, and - for Markdown files - relative file path links and section anchors.
31 changes: 31 additions & 0 deletions manifest-verifier/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: 'verify-manifest'
description: 'Verifies manifest.yml against missing submodule entires and stale version information'
inputs:
path:
description: 'Path to repository folder containing manifest.yml to verify.'
required: false
default: ./
exclude-submodules:
description: 'List of comma-separated relative path to submodules that should not be present in manifest.yml. Eg libraries/thirdparty/tinycbor,libraries/thirdparty/mbedtls'
required: false
default: ''
fail-on-incorrect-version:
description: 'Boolean flag to indicate if verification should fail if any submodule version in manifest.yml file is incorrect or stale.'
required: false
default: 'false'
runs:
using: "composite"
steps:
- name: Install dependencies
run: pip install -r $GITHUB_ACTION_PATH/requirements.txt
shell: bash
- name: Run verifier script
working-directory: ${{ inputs.path }}
run: |
if [[ "${{ inputs.fail-on-incorrect-version }}" == "true" ]]; then
echo 'Value of flag is ${{ inputs.fail-on-incorrect-version }}'
python3 $GITHUB_ACTION_PATH/verify_manifest.py --ignore-submodule-path=${{ inputs.exclude-submodules }} --fail-on-incorrect-version
else
python3 $GITHUB_ACTION_PATH/verify_manifest.py --ignore-submodule-path=${{ inputs.exclude-submodules }}
fi
shell: bash
2 changes: 2 additions & 0 deletions manifest-verifier/requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pyyaml
gitpython
118 changes: 118 additions & 0 deletions manifest-verifier/verify_manifest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#!/usr/bin/env python3

import os, sys
from yaml import load
from yaml import CLoader as Loader

from git import Repo
from argparse import ArgumentParser

REPO_PATH=''

# List of submodules excluded from manifest.yml file
IGNORE_SUBMODULES_LIST = []

# Obtain submodule path of all entries in manifest.yml file.
def read_manifest():
dict = {}

# Read YML file
path_manifest = os.path.join(REPO_PATH, 'manifest.yml')
assert os.path.exists(path_manifest), 'Missing manifest.yml'
with open(path_manifest, 'r') as fp:
manifest_data = fp.read()
yml = load(manifest_data, Loader=Loader)
assert 'dependencies' in yml, 'Manifest YML parsing error'

# Iterate over all the "dependencies" entries, verify that
# each contains entries for the following hierarchy:
# name: "<library-name>"
# version: "<version>"
# repository:
# type: "git"
# url: <library-github-url>
# path: <path-to-submodule-in-repository>
#
for dep in yml['dependencies']:
assert 'version' in dep, "Failed to parse 'version/tag' for submodule"
assert 'repository' in dep and 'path' in dep['repository'] and 'url' in dep['repository'], "Failed to parse 'repository' object for submodule"
dict[dep['name']] = (dep['repository']['path'], dep['version'])

return dict

# Generate list of submodules path in repository, excluding the
# path in IGNORES_SUBMODULES_LIST.
def get_all_submodules():
info_dict = {}
repo = Repo(REPO_PATH)
for submodule in repo.submodules:
path = submodule.abspath.replace(REPO_PATH+'/', '')
if path not in IGNORE_SUBMODULES_LIST:
#print(path,':',submodule.module().head.commit)
info_dict[path] = submodule.module().head.commit

return info_dict

if __name__ == '__main__':
parser = ArgumentParser(description='manifest.yml verifier')
parser.add_argument('--repo-root-path',
type=str,
required=None,
default=os.getcwd(),
help='Path to the repository root.')
parser.add_argument('--ignore-submodule-path',
type=str,
required=None,
help='Comma-separated list of submodules path to ignore.')
parser.add_argument('--fail-on-incorrect-version',
action='store_true',
help='Flag to indicate script to fail for incorrect submodules versions in manifest.yml')

args = parser.parse_args()

if args.ignore_submodule_path != None:
IGNORE_SUBMODULES_LIST = args.ignore_submodule_path.split(',')

# Convert any relative path (like './') in passed argument to absolute path.
REPO_PATH = os.path.abspath(args.repo_root_path)

submodules_info_from_manifest = read_manifest()
submodule_path_from_manifest = [pair[0] for pair in submodules_info_from_manifest.values()]
submodule_path_from_manifest = sorted(submodule_path_from_manifest)

submodules_info_from_git = get_all_submodules()
submodule_path_from_git = sorted(submodules_info_from_git.keys())

print(REPO_PATH)
print('\nList of submoduled libraries being verified:', submodule_path_from_git)

# Check that manifest.yml contains entries for all submodules
# present in repository.
if submodule_path_from_manifest != submodule_path_from_git:
print('manifest.yml is missing entries for:')
# Find list of library submodules missing in manifest.yml
for git_path in submodule_path_from_git:
if git_path not in submodule_path_from_manifest:
print(git_path)
sys.exit(1)

# Verify that manifest contains correct versions of submodules pointers.
mismatch_flag = False
print('\nVerifying that manifest.yml versions are up-to-date.....')
for submodule_name, submodule_info in submodules_info_from_manifest.items():
relative_path = submodule_info[0]
manifest_commit = submodule_info[1]
submodule = Repo(REPO_PATH+'/'+relative_path)
submodule.remote('origin').fetch()
submodule.git.checkout(manifest_commit)
if (submodules_info_from_git[relative_path] != submodule.head.commit):
print('manifest.yml does not have correct commit ID for', submodule_name,'manifest Commit=(',manifest_commit, submodule.head.commit,') Actual Commit=',submodules_info_from_git[relative_path])
mismatch_flag = True

if mismatch_flag and args.fail_on_incorrect_version:
sys.exit(1)

print('\nmanifest.yml file has been verified!')
sys.exit(0)


0 comments on commit 35c9714

Please sign in to comment.