From 5fc2a01d139a152e8b4757d6697ff5ab9648e28a Mon Sep 17 00:00:00 2001 From: Alvin Schiller <103769832+AlvinSchiller@users.noreply.github.com> Date: Tue, 17 Oct 2023 20:48:29 +0200 Subject: [PATCH] unified workflow base for debian --- .github/workflows/docker_debian_unified.yml | 185 ++++++++++++++++++ ...ckerfile.debian.test_install_unified.armv7 | 78 ++++++++ 2 files changed, 263 insertions(+) create mode 100644 .github/workflows/docker_debian_unified.yml create mode 100644 ci/Dockerfile.debian.test_install_unified.armv7 diff --git a/.github/workflows/docker_debian_unified.yml b/.github/workflows/docker_debian_unified.yml new file mode 100644 index 000000000..67477d80d --- /dev/null +++ b/.github/workflows/docker_debian_unified.yml @@ -0,0 +1,185 @@ +name: Test Install Scripts Debian Unified + +# let only one instance run the test so cache is not corrupted. +# cancel already running instances as only the last run will be relevant +concurrency: + group: ${{ github.ref }}-debian + cancel-in-progress: true + +on: + schedule: + # run at 5 every sunday + - cron: '0 5 * * 0' + push: + branches-ignore: + - 'future3/**' + pull_request: + # The branches below must be a subset of the branches above + branches: [ develop ] + +env: + DOCKER_IMAGE_NAME: rpi-jukebox-rfid + CACHE_SCOPE: ${{ github.ref }}-debian + LOCAL_REGISTRY_PORT: 5000 + MATRIX_DEBIAN_VERSION_NAME: "['bullseye', 'buster']" + MATRIX_USERNAME: "['pi', 'hans']" + MATRIX_TEST_SCRIPT: "['run_installation_tests.sh', 'run_installation_tests2.sh', 'run_installation_tests3.sh']" + +jobs: + prepare: + runs-on: ubuntu-latest + + outputs: + runs_on: ubuntu-latest + platform: linux/arm/v7 + + matrix_debian_version_name: ${{ env.MATRIX_DEBIAN_VERSION_NAME }} + matrix_username: ${{ env.MATRIX_USERNAME }} + matrix_test_script: ${{ env.MATRIX_TEST_SCRIPT }} + + image_tag_name: ${{ steps.set-image_tag_name.outputs.image_tag_name }} + image_tag_name_local_base: ${{ steps.set-image_tag_name_local_base.outputs.image_tag_name_local_base }} + image_file_path: ${{ steps.set-image_file_path.outputs.image_file_path }} + cache_scope: ${{ steps.set-cache_scope.outputs.cache_scope }} + cache_key: ${{ steps.set-cache_key.outputs.cache_key }} + local_registry_port: ${{ steps.set-local_registry_port.outputs.local_registry_port }} + + steps: + - name: Set Output cache_scope + id: set-cache_scope + run: echo "cache_scope=${{ env.CACHE_SCOPE }}-{0}" >> $GITHUB_OUTPUT + + - name: Set Output image_tag_name + id: set-image_tag_name + run: echo "image_tag_name=${{ env.DOCKER_IMAGE_NAME }}:{0}-test" >> $GITHUB_OUTPUT + + - name: Set Output image_file_path + id: set-image_file_path + run: echo "image_file_path=./${{ env.DOCKER_IMAGE_NAME }}-{0}.tar" >> $GITHUB_OUTPUT + + - name: Set Output cache_key + id: set-cache_key + run: echo "cache_key=${{ steps.set-cache_scope.outputs.cache_scope }}-${{ github.sha }}#${{ github.run_attempt }}" >> $GITHUB_OUTPUT + + - name: Set Output local_registry_port + id: set-local_registry_port + run: echo "local_registry_port=${{ env.LOCAL_REGISTRY_PORT }}" >> $GITHUB_OUTPUT + + - name: Set Output image_tag_name_local_base + id: set-image_tag_name_local_base + run: echo "image_tag_name_local_base=localhost:${{ steps.set-local_registry_port.outputs.local_registry_port }}/${{ steps.set-image_tag_name.outputs.image_tag_name }}-base" >> $GITHUB_OUTPUT + + build: + needs: [prepare] + runs-on: ${{ needs.prepare.outputs.runs_on }} + services: + registry: + image: registry:2 + ports: + - ${{ needs.prepare.outputs.local_registry_port }}:5000 + + strategy: + fail-fast: false + matrix: + debian_version_name: ${{ fromJSON(needs.prepare.outputs.matrix_debian_version_name) }} + + steps: + - uses: actions/checkout@v4 + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + with: + # network=host driver-opt needed to push to local registry + driver-opts: network=host + + - name: Build Image - Base + uses: docker/build-push-action@v5 + with: + context: . + load: false + push: true + file: ./ci/Dockerfile.debian.test_install_unified.armv7 + target: test + platforms: ${{ needs.prepare.outputs.platform }} + tags: ${{ format( needs.prepare.outputs.image_tag_name_local_base, matrix.debian_version_name) }} + cache-from: type=gha,scope=${{ format( needs.prepare.outputs.cache_scope, matrix.debian_version_name) }} + cache-to: type=gha,mode=max,scope=${{ format( needs.prepare.outputs.cache_scope, matrix.debian_version_name) }} + build-args: | + DEBIAN_VERSION_NAME=${{ matrix.debian_version_name }} + GIT_BRANCH=${{ github.ref_name }} + GIT_URL=${{ github.server_url }}/${{ github.repository }} + + + - name: Build Image - Update + uses: docker/build-push-action@v5 + with: + context: . + load: false + push: false + file: ./ci/Dockerfile.debian.test_install_unified.armv7 + target: test-update + platforms: ${{ needs.prepare.outputs.platform }} + tags: ${{ format( needs.prepare.outputs.image_tag_name, matrix.debian_version_name) }} + cache-from: type=gha,scope=${{ format( needs.prepare.outputs.cache_scope, matrix.debian_version_name) }} + # DON'T use 'cache-to' here as the layer is then cached and this build would be useless + outputs: type=docker,dest=${{ format( needs.prepare.outputs.image_file_path, matrix.debian_version_name) }} + build-args: | + BASE_TEST_IMAGE=${{ format( needs.prepare.outputs.image_tag_name_local_base, matrix.debian_version_name) }} + + + - name: Cache Check Docker Image + uses: actions/cache/restore@v3 + id: cache-restore + with: + lookup-only: true + key: ${{ format( needs.prepare.outputs.cache_key, matrix.debian_version_name) }} + path: ${{ format( needs.prepare.outputs.image_file_path, matrix.debian_version_name) }} + + - name: Cache Save Docker Image + uses: actions/cache/save@v3 + if: ${{ ! steps.cache-restore.outputs.cache-hit }} + with: + key: ${{ steps.cache-restore.outputs.cache-primary-key }} + path: ${{ format( needs.prepare.outputs.image_file_path, matrix.debian_version_name) }} + + + test: + needs: [prepare, build] + runs-on: ${{ needs.prepare.outputs.runs_on }} + + strategy: + fail-fast: false + matrix: + debian_version_name: ${{ fromJSON(needs.prepare.outputs.matrix_debian_version_name) }} + username: ${{ fromJSON(needs.prepare.outputs.matrix_username) }} + test_script: ${{ fromJSON(needs.prepare.outputs.matrix_test_script) }} + + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3.0.0 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3.0.0 + + - name: Cache Restore Docker Image + uses: actions/cache/restore@v3 + with: + key: ${{ format( needs.prepare.outputs.cache_key, matrix.debian_version_name) }} + path: ${{ format( needs.prepare.outputs.image_file_path, matrix.debian_version_name) }} + fail-on-cache-miss: true + + - name: Load Docker Image + run: | + docker load --input ${{ format( needs.prepare.outputs.image_file_path, matrix.debian_version_name) }} + + - name: Run Test ${{ matrix.debian_version_name }}-${{ matrix.username }}-${{ matrix.test_script }} + uses: tj-actions/docker-run@v2 + with: + image: ${{ format( needs.prepare.outputs.image_tag_name, matrix.debian_version_name) }} + options: --platform ${{ needs.prepare.outputs.platform }} --user ${{ matrix.username }} + name: ${{ matrix.test_script }} + args: | + ./${{ matrix.test_script }} diff --git a/ci/Dockerfile.debian.test_install_unified.armv7 b/ci/Dockerfile.debian.test_install_unified.armv7 new file mode 100644 index 000000000..4e039e421 --- /dev/null +++ b/ci/Dockerfile.debian.test_install_unified.armv7 @@ -0,0 +1,78 @@ +# Target to build and install all needed base configuration and packages +ARG DEBIAN_VERSION_NAME=bullseye +ARG BASE_TEST_IMAGE=test +FROM debian:${DEBIAN_VERSION_NAME}-slim as base +ARG DEBIAN_VERSION_NAME + +ENV DOCKER_RUNNING=true +RUN touch /boot/cmdlinetxt + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && apt-get -y install \ + apt-utils \ + curl \ + gnupg \ + && echo "deb http://raspbian.raspberrypi.org/raspbian/ ${DEBIAN_VERSION_NAME} main contrib non-free rpi" > /etc/apt/sources.list.d/raspi.list \ + && echo "deb http://archive.raspberrypi.org/debian/ ${DEBIAN_VERSION_NAME} main" >> /etc/apt/sources.list.d/raspi.list \ + && curl http://raspbian.raspberrypi.org/raspbian.public.key | apt-key add - \ + && curl http://archive.raspberrypi.org/debian/raspberrypi.gpg.key | apt-key add - \ + && apt-get update \ + && apt-get -y upgrade \ + && apt-get -y install \ + build-essential \ + git \ + iw \ + locales \ + sudo \ + systemd \ + wget \ + wpasupplicant \ + # install internally used packages here to speed up GitHub Action + raspberrypi-kernel \ + raspberrypi-kernel-headers \ + && rm -rf /var/lib/apt/lists/* +# ------ + + +# Target for setting up user for test. user can be selected with the docker '--user $USERNAME' option +FROM base as user +ENV TEST_USER_GROUP=test + + # Group used for assigning file permissions +RUN groupadd --gid 1002 $TEST_USER_GROUP + +RUN export USER_PI=pi \ + && export USER_PI_GROUP=$USER_PI \ + && groupadd --gid 1000 $USER_PI_GROUP \ + && useradd -u 1000 -g $USER_PI_GROUP -G sudo,$TEST_USER_GROUP -d /home/$USER_PI -m -s /bin/bash -p '$1$iV7TOwOe$6ojkJQXyEA9bHd/SqNLNj0' $USER_PI \ + && echo "$USER_PI ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER_PI + +RUN export USER_ALT=hans \ + && export USER_ALT_GROUP=wurst \ + && groupadd --gid 1001 $USER_ALT_GROUP \ + && useradd -u 1001 -g $USER_ALT_GROUP -G sudo,$TEST_USER_GROUP -d /home/$USER_ALT -m -s /bin/bash -p '$1$iV7TOwOe$6ojkJQXyEA9bHd/SqNLNj0' $USER_ALT \ + && echo "$USER_ALT ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/$USER_ALT +# ------ + + +# Target for adding envs and scripts from the repo to test installation +FROM user as test +ARG GIT_BRANCH +ARG GIT_URL + +ENV GIT_BRANCH=$GIT_BRANCH GIT_URL=$GIT_URL + +COPY --chown=root:$TEST_USER_GROUP --chmod=770 scripts/installscripts/buster-install-default.sh . +WORKDIR /tests +COPY --chown=root:$TEST_USER_GROUP --chmod=770 scripts/installscripts/tests/*.sh . +# ------ + + +# Target for applying latest updates (should not be cached!) +FROM $BASE_TEST_IMAGE as test-update +RUN apt-get update \ + && apt-get -y upgrade \ + && rm -rf /var/lib/apt/lists/* +# ------