Add workflow to check entangled specs (#531)

This commit is contained in:
Thomas Crain 2021-01-11 15:17:56 -06:00 committed by GitHub
parent 4fb6bc0ebf
commit 6dffb4a58b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 123 additions and 0 deletions

View File

@ -0,0 +1,35 @@
# This action checks that certain groups of specs have matching tags.
# The main use case is to ensure that signed specs have the same Version and
# Release tags as their unsigned counterparts
name: Spec Entanglement Mismatch Check
on:
push:
paths:
- "**.spec"
branches: [main, dev, 1.0*]
pull_request:
paths:
- "**.spec"
branches: [main, dev, 1.0*]
jobs:
check:
runs-on: ubuntu-latest
steps:
# Checkout the branch of our repo that triggered this action
- name: Workflow trigger checkout
uses: actions/checkout@v2
# For consistency, we use the same major/minor version of Python that CBL-Mariner ships
- name: Setup Python 3.7
uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Get Python dependencies
run: python3 -m pip install python-rpm-spec
- name: Run entanglement checking script
run: python3 ./.github/workflows/check_entangled_specs.py .

View File

@ -0,0 +1,88 @@
from typing import FrozenSet, List, Set
from pyrpm.spec import Spec
import argparse
from collections import defaultdict
from pathlib import Path
import pprint
import sys
version_release_matching_groups = [
frozenset([
"SPECS-SIGNED/kernel-signed-x64/kernel-signed-x64.spec",
"SPECS-SIGNED/kernel-signed-aarch64/kernel-signed-aarch64.spec",
"SPECS/kernel/kernel.spec",
"SPECS/kernel-headers/kernel-headers.spec"
]),
frozenset([
"SPECS-SIGNED/grub2-efi-binary-signed-x64/grub2-efi-binary-signed-x64.spec",
"SPECS-SIGNED/grub2-efi-binary-signed-aarch64/grub2-efi-binary-signed-aarch64.spec",
"SPECS/grub2/grub2.spec"
])
]
version_matching_groups = [
frozenset([
"SPECS/hyperv-daemons/hyperv-daemons.spec",
"SPECS/kernel/kernel.spec",
"SPECS/kernel-hyperv/kernel-hyperv.spec"
])
]
def check_spec_tags(base_path: str, tags: List[str], groups: List[FrozenSet]) -> Set[FrozenSet]:
"""Returns spec sets which violate matching rules for given tags. """
err_groups = set()
for group in groups:
variants = defaultdict(set)
for spec_filename in group:
parsed_spec = Spec.from_file(Path(base_path, spec_filename))
for tag in tags:
variants[tag].add(getattr(
parsed_spec, tag))
for tag in tags:
if len(variants[tag]) > 1:
err_groups.add(group)
return err_groups
def check_version_release_match_groups(base_path: str) -> Set[FrozenSet]:
return check_spec_tags(base_path, ['version', 'release'], version_release_matching_groups)
def check_version_match_groups(base_path: str) -> Set[FrozenSet]:
return check_spec_tags(base_path, ['version'], version_matching_groups)
def check_matches(base_path: str):
version_match_errors = check_version_match_groups(base_path)
version_release_match_errors = check_version_release_match_groups(
base_path)
printer = pprint.PrettyPrinter()
if len(version_match_errors) or len(version_release_match_errors):
print('The current repository state violates a spec entanglement rule!')
if len(version_match_errors):
print(
'\nPlease update the following sets of specs to have the same Version tags:')
for e in version_match_errors:
printer.pprint(e)
if len(version_release_match_errors):
print(
'\nPlease update the following sets of specs to have the same Version and Release tags:')
for e in version_release_match_errors:
printer.pprint(e)
sys.exit(1)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument(
'repo_root', help='path to the root of the CBL-Mariner repository')
args = parser.parse_args()
check_matches(args.repo_root)