diff --git a/.github/scripts/create_inputs.py b/.github/scripts/create_inputs.py new file mode 100644 index 0000000..063851b --- /dev/null +++ b/.github/scripts/create_inputs.py @@ -0,0 +1,34 @@ +import json +import os +import re +import subprocess + +re_image = re_dockerfile = '' +changed_files = json.loads(os.environ['CHANGED_FILES']) +with open('images.json') as fd: + builds = json.load(fd) + + dockerfiles = list(map(lambda v: v.removesuffix('.dockerfile'), filter(lambda v: re.match('.*dockerfile$', v), changed_files))) + if len(dockerfiles) > 0: + re_dockerfile = '|'.join(dockerfiles) + + if 'images.json' in changed_files: + try: + data = subprocess.run(['git', 'show', 'HEAD^:images.json'], stdout=subprocess.PIPE).stdout.decode('utf-8') + images = json.loads(data) + with open('images.json', 'r') as fd: + new_images = json.load(fd) + diff = list(filter(lambda v: v not in images, new_images)) + if len(diff) > 0: + re_image = '|'.join(map(lambda v: f"{v['image']}:{v['tag']}", diff)) + except json.decoder.JSONDecodeError: + re_image = '.*' + + with open(os.environ['GITHUB_OUTPUT'], 'a') as output: + if re_dockerfile == re_image: + print('do_build=false', file=output) + print('::notice title=::no image build changes detected') + else: + print('do_build=true', file=output) + print(f're_dockerfile=({re_dockerfile})', file=output) + print(f're_image=({re_image})', file=output) diff --git a/.github/scripts/set_matrix.py b/.github/scripts/set_matrix.py new file mode 100644 index 0000000..5112367 --- /dev/null +++ b/.github/scripts/set_matrix.py @@ -0,0 +1,43 @@ +import json +import os +from re import match + +# parse workflow inputs +image = os.environ['image'] +dockerfile = os.environ['dockerfile'] +refresh = True if os.environ['refresh'] == "true" else False + +# output +matrix = [] + +# load matrix json +with open('images.json') as fd: + builds = json.load(fd) + for i, v in enumerate(builds): + builds[i]['image_tag'] = f"{v['image']}:{v['tag']}" + builds[i]['base_image_tag'] = f"{v['base_image']}:{v['base_tag']}" + builds[i]['refresh'] = refresh + +if dockerfile: + dockerfile = f"^{dockerfile}$" + for _, v in enumerate(builds): + if match(dockerfile, v['dockerfile']): + # always refresh + v['refresh'] = True + matrix.append(v) + +if image: + image = f"^{image}$" if image else image + for _, v in enumerate(builds): + if match(image, v['image_tag']): + matrix.append(v) + +# unique list of images +matrix = list({v['image_tag']:v for v in matrix}.values()) + +if len(matrix) == 0: + print("::error title::failed to build matrix, no images matched?") + raise SystemExit(1) + +with open(os.environ['GITHUB_OUTPUT'], 'a') as output: + print('matrix=' + json.dumps({ 'include': matrix }), file=output) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 805d134..b1f181c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -27,42 +27,8 @@ jobs: quotepath: false - name: Create inputs id: create-inputs - shell: python {0} run: | - import json - import os - import re - import subprocess - - re_image = re_dockerfile = '' - changed_files = json.loads("${{ steps.changed-files.outputs.all_changed_files }}") - with open('images.json') as fd: - builds = json.load(fd) - - dockerfiles = list(map(lambda v: v.removesuffix('.dockerfile'), filter(lambda v: re.match('.*dockerfile$', v), changed_files))) - if len(dockerfiles) > 0: - re_dockerfile = '|'.join(dockerfiles) - - if 'images.json' in changed_files: - try: - data = subprocess.run(['git', 'show', 'HEAD^:images.json'], stdout=subprocess.PIPE).stdout.decode('utf-8') - images = json.loads(data) - with open('images.json', 'r') as fd: - new_images = json.load(fd) - diff = list(filter(lambda v: v not in images, new_images)) - if len(diff) > 0: - re_image = '|'.join(map(lambda v: f"{v['image']}:{v['tag']}", diff)) - except json.decoder.JSONDecodeError: - re_image = '.*' - - with open(os.environ['GITHUB_OUTPUT'], 'a') as output: - if re_dockerfile == re_image: - print('do_build=false', file=output) - print('::notice title=::no image build changes detected') - else: - print('do_build=true', file=output) - print(f're_dockerfile=({re_dockerfile})', file=output) - print(f're_image=({re_image})', file=output) + CHANGED_FILES='${{ steps.changed-files.outputs.all_changed_files }}' python .github/scripts/create_inputs.py build: needs: prepare diff --git a/.github/workflows/template_build_deploy.yml b/.github/workflows/template_build_deploy.yml index b5c14fe..4663213 100644 --- a/.github/workflows/template_build_deploy.yml +++ b/.github/workflows/template_build_deploy.yml @@ -26,6 +26,9 @@ env: REGISTRY_USERNAME: ${{ vars.DOCKER_USERNAME != '' && vars.DOCKER_USERNAME || github.actor }} REGISTRY_PASSWORD: ${{ secrets.DOCKER_PASSWORD != '' && secrets.DOCKER_PASSWORD || secrets.GITHUB_TOKEN }} REPOSITORY: ${{ vars.DOCKER_REPOSITORY != '' && vars.DOCKER_REPOSITORY || github.repository }} + image: ${{ github.event.inputs.image }} + dockerfile: ${{ github.event.inputs.dockerfile }} + refresh: ${{ github.event.inputs.refresh }} jobs: select: @@ -42,51 +45,8 @@ jobs: - name: Create matrix from json id: set-matrix - shell: python {0} run: | - import json - import os - from re import match - - # parse workflow inputs - image = "${{ inputs.image }}" - dockerfile = "${{ inputs.dockerfile }}" - refresh = True if "${{ inputs.refresh }}" == "true" else False - - # output - matrix = [] - - # load matrix json - with open('images.json') as fd: - builds = json.load(fd) - for i, v in enumerate(builds): - builds[i]['image_tag'] = f"{v['image']}:{v['tag']}" - builds[i]['base_image_tag'] = f"{v['base_image']}:{v['base_tag']}" - builds[i]['refresh'] = refresh - - if dockerfile: - dockerfile = f"^{dockerfile}$" - for _, v in enumerate(builds): - if match(dockerfile, v['dockerfile']): - # always refresh - v['refresh'] = True - matrix.append(v) - - if image: - image = f"^{image}$" if image else image - for _, v in enumerate(builds): - if match(image, v['image_tag']): - matrix.append(v) - - # unique list of images - matrix = list({v['image_tag']:v for v in matrix}.values()) - - if len(matrix) == 0: - print("::error title::failed to build matrix, no images matched?") - raise SystemExit(1) - - with open(os.environ['GITHUB_OUTPUT'], 'a') as output: - print('matrix=' + json.dumps({ 'include': matrix }), file=output) + python .github/scripts/set_matrix.py - if: inputs.push name: Get branch names