diff --git a/.github/workflows/pr-check-duplicated-image.yml b/.github/workflows/pr-check-duplicated-image.yml new file mode 100644 index 000000000..0cdba415a --- /dev/null +++ b/.github/workflows/pr-check-duplicated-image.yml @@ -0,0 +1,40 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +name: Check Duplicated Images + +on: + pull_request: + branches: [main] + types: [opened, reopened, ready_for_review, synchronize] + paths: + - "**/docker_image_build/*.yaml" + - ".github/workflows/pr-check-duplicated-image.yml" + - ".github/workflows/scripts/check_duplicated_image.py" + workflow_dispatch: + +# If there is a new commit, the previous jobs will be canceled +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + check-duplicated-image: + runs-on: ubuntu-latest + steps: + - name: Clean Up Working Directory + run: sudo rm -rf ${{github.workspace}}/* + + - name: Checkout Repo + uses: actions/checkout@v4 + + - name: Check all the docker image build files + run: | + pip install PyYAML + cd ${{github.workspace}} + build_files="" + for f in `find . -path "*/docker_image_build/build.yaml"`; do + build_files="$build_files $f" + done + python3 .github/workflows/scripts/check_duplicated_image.py $build_files + shell: bash diff --git a/.github/workflows/scripts/check_duplicated_image.py b/.github/workflows/scripts/check_duplicated_image.py new file mode 100644 index 000000000..cd5f0cddf --- /dev/null +++ b/.github/workflows/scripts/check_duplicated_image.py @@ -0,0 +1,63 @@ +# Copyright (C) 2024 Intel Corporation +# SPDX-License-Identifier: Apache-2.0 + +import argparse +import os.path +import subprocess +import sys + +import yaml + +images = {} + + +def check_docker_compose_build_definition(file_path): + with open(file_path, "r") as f: + data = yaml.load(f, Loader=yaml.FullLoader) + for service in data["services"]: + if "build" in data["services"][service] and "image" in data["services"][service]: + bash_command = "echo " + data["services"][service]["image"] + image = ( + subprocess.run(["bash", "-c", bash_command], check=True, capture_output=True) + .stdout.decode("utf-8") + .strip() + ) + build = data["services"][service]["build"] + context = build.get("context", "") + dockerfile = os.path.normpath( + os.path.join(os.path.dirname(file_path), context, build.get("dockerfile", "")) + ) + if not os.path.exists(dockerfile): + # dockerfile not exists in the current repo context, assume it's in 3rd party context + dockerfile = os.path.normpath(os.path.join(context, build.get("dockerfile", ""))) + item = {"file_path": file_path, "service": service, "dockerfile": dockerfile} + if image in images and dockerfile != images[image]["dockerfile"]: + print("ERROR: !!! Found Conflicts !!!") + print(f"Image: {image}, Dockerfile: {dockerfile}, defined in Service: {service}, File: {file_path}") + print( + f"Image: {image}, Dockerfile: {images[image]['dockerfile']}, defined in Service: {images[image]['service']}, File: {images[image]['file_path']}" + ) + sys.exit(1) + else: + # print(f"Add Image: {image} Dockerfile: {dockerfile}") + images[image] = item + + +def parse_arg(): + parser = argparse.ArgumentParser( + description="Check for conflicts in image build definition in docker-compose.yml files" + ) + parser.add_argument("files", nargs="+", help="list of files to be checked") + return parser.parse_args() + + +def main(): + args = parse_arg() + for file_path in args.files: + check_docker_compose_build_definition(file_path) + print("SUCCESS: No Conlicts Found.") + return 0 + + +if __name__ == "__main__": + main()