From 14ef21b753fcd6803aaefc0f2622f548b899d342 Mon Sep 17 00:00:00 2001 From: Sorin Sbarnea Date: Sat, 28 Sep 2024 13:09:56 +0100 Subject: [PATCH] gha: replace build-test composite action with a reusable workflow --- .github/actions/build-test/action.yml | 136 -------------------------- .github/workflows/.build-image.yml | 113 +++++++++++++++++++++ .github/workflows/tox.yml | 60 +++--------- tox.ini | 11 ++- 4 files changed, 131 insertions(+), 189 deletions(-) delete mode 100644 .github/actions/build-test/action.yml create mode 100644 .github/workflows/.build-image.yml diff --git a/.github/actions/build-test/action.yml b/.github/actions/build-test/action.yml deleted file mode 100644 index dc2a724..0000000 --- a/.github/actions/build-test/action.yml +++ /dev/null @@ -1,136 +0,0 @@ ---- -name: Build & Test -description: Build the final container image and run tests on it - -inputs: - registry: - description: Target registry to push the final image. - default: "localhost:5000" - namespace: - description: Namespace of the container image. - default: ansible - final_image: - description: Name of the final image. - default: community-ansible-dev-tools - push: - description: If it should push the result of not. Accepts only true / false strings. - default: "false" -runs: - using: composite - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Prepare - shell: bash - run: | - platform=${{ matrix.platform }} - echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV - sudo apt install -y python3-pip python3-build pipx - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - with: - # network=host driver-opt needed to push to local registry - driver-opts: network=host - buildkitd-flags: --debug - - - name: Install or upgrade tools needed for the build and test - shell: bash - id: ansible-builder-install - run: | - set -ex - python3 -m pipx install --force ansible-builder - python3 -m build --outdir final/dist/ --wheel - - - name: Create a build context and Containerfile for base EE - shell: bash - run: | - ansible-builder create -f ${{ github.workspace }}/execution-environment.yml --output-filename Containerfile -v3 - - - name: Build base image for ${{ matrix.platform }} - uses: docker/build-push-action@v6 - id: build-base - with: - context: context - provenance: false - file: context/Containerfile - platforms: ${{ matrix.platform }} - push: true - tags: localhost:5000/${{ inputs.final_image }}-base:latest - cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }} - cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }} - - - name: Show available images & base image manifest - shell: bash - run: | - curl -X GET http://localhost:5000/v2/${{ inputs.final_image }}-base/tags/list - docker manifest inspect localhost:5000/${{ inputs.final_image }}-base --insecure -v - - - name: Build final image for ${{ matrix.platform }} - id: build-final - uses: docker/build-push-action@v6 - env: - DOCKER_BUILD_SUMMARY: "false" - with: - context: ${{ github.workspace }}/final - provenance: false - file: ${{ github.workspace }}/final/Containerfile - load: true - tags: | - ${{ inputs.namespace }}/${{ inputs.final_image }}:test - build-contexts: | - ${{ inputs.final_image }}-base=docker-image://localhost:5000/${{ inputs.final_image }}-base:latest - platforms: ${{ matrix.platform }} - cache-from: type=gha,scope=build-${{ env.PLATFORM_PAIR }} - cache-to: type=gha,scope=build-${{ env.PLATFORM_PAIR }} - - - name: Squash image layers to save disk space - shell: bash - run: | - python3 -m pipx install --force docker-squash - docker-squash ${{ inputs.namespace }}/${{ inputs.final_image }}:test - - - name: Run tests against the container - shell: bash - run: | - python3 -m pipx install --force "tox>=4.0.0" - tox -e test-image -- --container-engine docker --image-name ${{ inputs.namespace }}/${{ inputs.final_image }}:test - - - name: Push the built image to ${{ inputs.registry }} by digest for ${{ matrix.platform }} - id: push-final - if: inputs.push == 'true' - uses: docker/build-push-action@v6 - with: - context: ${{ github.workspace }}/final - provenance: false - file: ${{ github.workspace }}/final/Containerfile - build-contexts: | - ${{ inputs.final_image }}-base=docker-image://localhost:5000/${{ inputs.final_image }}-base:latest - platforms: ${{ matrix.platform }} - outputs: type=image,name=${{ inputs.registry }}/${{ inputs.namespace }}/${{ inputs.final_image }},push-by-digest=true,name-canonical=true,push=true - - - name: Export digest - if: inputs.push == 'true' - shell: bash - run: | - rm -rf /tmp/digests - mkdir -p /tmp/digests - digest="${{ steps.push-final.outputs.digest }}" - touch "/tmp/digests/${digest#sha256:}" - - - name: Upload digest - if: inputs.push == 'true' - uses: actions/upload-artifact@v4 - with: - name: digests-${{ env.PLATFORM_PAIR }} - path: /tmp/digests/* - if-no-files-found: error - retention-days: 1 - - # this step is ONLY needed for maintainence of self hosted runners - - name: Cleanup docker - shell: bash - if: always() - run: | - docker system prune -af --volumes diff --git a/.github/workflows/.build-image.yml b/.github/workflows/.build-image.yml new file mode 100644 index 0000000..70b572e --- /dev/null +++ b/.github/workflows/.build-image.yml @@ -0,0 +1,113 @@ +--- +name: Build & Test +# description: Build the final container image and run tests on it + +on: + workflow_call: + inputs: + registry: + type: string + description: Target registry to push the final image. + default: ghcr.io + namespace: + description: Namespace of the container image. + default: ansible + type: string + final_image: + description: Name of the final image. + default: community-ansible-dev-tools + type: string + push: + description: If it should push the result of not. Accepts only true / false strings. + default: ${{ github.event_name == 'release' && github.event.action == 'published' }} + type: string +jobs: + build-test: + runs-on: ${{ matrix.builder }} + name: ${{ matrix.name }} + strategy: + fail-fast: false + matrix: + include: + - builder: devtools-multiarch-builder + platform: linux/amd64 + name: amd64 + - builder: devtools-arm64-runner + platform: linux/arm64 + name: arm64 + services: + registry: + image: registry:2 + ports: + - 5000:5000 + + steps: + - name: Check out repository + uses: actions/checkout@v4 + + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Prune docker system + run: sudo ./final/docker-prune.sh + + - name: Prepare + shell: bash + run: | + platform=${{ matrix.platform }} + echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV + sudo apt install -y python3-pip python3-build pipx + pipx install tox + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + # network=host driver-opt needed to push to local registry + driver-opts: network=host + buildkitd-flags: --debug + + - name: Run tox -e ee + shell: bash + run: tox -e ee + + - name: Push the built image to ${{ inputs.registry }} by digest for ${{ matrix.platform }} + id: push-final + if: inputs.push == 'true' + uses: docker/build-push-action@v6 + with: + context: ${{ github.workspace }}/final + provenance: false + file: ${{ github.workspace }}/final/Containerfile + build-contexts: | + ${{ inputs.final_image }}-base=docker-image://localhost:5000/${{ inputs.final_image }}-base:latest + platforms: ${{ matrix.platform }} + outputs: type=image,name=${{ inputs.registry }}/${{ inputs.namespace }}/${{ inputs.final_image }},push-by-digest=true,name-canonical=true,push=true + + - name: Export digest + if: inputs.push == 'true' + shell: bash + run: | + rm -rf /tmp/digests + mkdir -p /tmp/digests + digest="${{ steps.push-final.outputs.digest }}" + touch "/tmp/digests/${digest#sha256:}" + + - name: Upload digest + if: inputs.push == 'true' + uses: actions/upload-artifact@v4 + with: + name: digests-${{ env.PLATFORM_PAIR }} + path: /tmp/digests/* + if-no-files-found: error + retention-days: 1 + + # this step is ONLY needed for maintainence of self hosted runners + - name: Cleanup docker + shell: bash + if: always() + run: | + docker system prune -af --volumes diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 6663839..8d4aba6 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -20,58 +20,17 @@ concurrency: cancel-in-progress: true jobs: - tox: - uses: ansible/team-devtools/.github/workflows/tox.yml@main - build-image: - runs-on: ${{ matrix.builder }} - name: ${{ matrix.name }} - # uses same runner for image building, but devspace image builds faster - needs: - - devspaces - services: - registry: - image: registry:2 - ports: - - 5000:5000 - - strategy: - fail-fast: false - matrix: - include: - - builder: devtools-multiarch-builder - platform: linux/amd64 - name: amd64 - - builder: devtools-arm64-runner - platform: linux/arm64 - name: arm64 - - steps: - - name: Check out repository - uses: actions/checkout@v4 - - - name: Login to GitHub Container Registry - uses: docker/login-action@v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Prune docker system - run: sudo ./final/docker-prune.sh - - - name: Build the container image for ${{ matrix.platform }} and test it - uses: ./.github/actions/build-test - # this needs to be passed only when on release pipeline: - with: - registry: ghcr.io - push: ${{ github.event_name == 'release' && github.event.action == 'published' }} + # tox: + # uses: ansible/team-devtools/.github/workflows/tox.yml@main + ee: + uses: ./.github/workflows/.build-image.yml publish-image: environment: release # approval runs-on: ubuntu-latest needs: - - build-image - - tox + - ee + # - tox if: github.event_name == 'release' && github.event.action == 'published' steps: - name: Check out repository @@ -91,6 +50,9 @@ jobs: devspaces: runs-on: devtools-multiarch-builder + # uses same runner for image building + needs: + - ee steps: - name: Check out repository uses: actions/checkout@v4 @@ -110,8 +72,8 @@ jobs: pypi: name: Publish to PyPI registry needs: - - build-image - - tox + - ee + # - tox if: github.event_name == 'release' && github.event.action == 'published' environment: release # approval runs-on: ubuntu-22.04 diff --git a/tox.ini b/tox.ini index 4dde7b6..4f4a4ab 100644 --- a/tox.ini +++ b/tox.ini @@ -18,6 +18,7 @@ package = editable extras = test pass_env = + ADT_CONTAINER_ENGINE CI CONTAINER_* DOCKER_* @@ -111,20 +112,22 @@ commands = python -m build --outdir {toxinidir}/dist/ {toxinidir} sh -c "python -m twine check --strict {toxinidir}/dist/*" -[testenv:image] +[testenv:ee] description = - Build the container image + Build and tests the execution environmwent (ee) container image skip_install = true deps = ansible-builder + ; docker-squash build setuptools # https://github.com/ansible/ansible-builder/issues/644 commands_pre = commands = python -m build --outdir {toxinidir}/final/dist/ --wheel {toxinidir} ansible-builder create -f execution-environment.yml --output-filename Containerfile -v3 - podman build --squash-all context/ --tag community-ansible-dev-tools-base:latest - podman build --squash-all final/ --tag community-ansible-dev-tools:test + {env:ADT_CONTAINER_ENGINE:podman} build --squash-all context/ --tag community-ansible-dev-tools-base:latest + {env:ADT_CONTAINER_ENGINE:podman} build --squash-all final/ --tag community-ansible-dev-tools:test + ; docker-squash ${{ inputs.namespace }}/${{ inputs.final_image }}:test pytest --only-container --image-name community-ansible-dev-tools:test allowlist_externals = podman