name: "Containers: Test-and-Build" on: workflow_dispatch: push: branches: - master paths: - '.containers/apps/**' - '.containers/base/**' - ".github/workflows/containers.build.yaml" pull_request: paths: - '.containers/apps/**' - '.containers/base/**' - ".github/workflows/containers.build.yaml" env: # How long to sleep before running the tests (gives the application time to start) GOSS_SLEEP: 30 # Detect which folders in project-root (which contain the containers) contain changes jobs: changes: name: Get changes runs-on: ubuntu-20.04 outputs: matrix: "{\"container\": ${{ steps.reduce.outputs.containers }} }" steps: - name: Checkout uses: actions/checkout@v2 - uses: dorny/paths-filter@v2 id: filter with: list-files: json filters: | changed: - '.containers/apps/**' - '.containers/base/**' - run: echo '${{ toJson(steps.filter.outputs) }}' > changes.json - id: reduce run: | CONTAINERS=$(jq --raw-output '.changed_files | fromjson | .[] |= sub("(?(?(?[\/]?)[^\/]+\/)(?(?[\/]?)[^\/]+\/(?(?[\/]?)[^\/]+)(?.+)))"; "\(.third_directory)") | unique' changes.json) echo ::set-output name=containers::${CONTAINERS} hadolint: name: Run hadolint runs-on: ubuntu-20.04 steps: - name: Checkout uses: actions/checkout@v2 - name: hadolint uses: reviewdog/action-hadolint@v1.18.0 with: github_token: ${{ secrets.GITHUB_TOKEN }} reporter: github-pr-review filter_mode: diff_context fail_on_error: true build: name: Build runs-on: ubuntu-20.04 needs: - hadolint - changes strategy: matrix: ${{ fromJson(needs.changes.outputs.matrix) }} fail-fast: false if: "!contains(github.event.head_commit.message, '[ci-skip]')" steps: - name: Checkout uses: actions/checkout@v2 # Define if tests and push should be run against which versions/platforms - name: Prepare id: prep run: | if test -f "./.containers/apps/${{ matrix.container }}/Dockerfile"; then CATEGORY="apps" else CATEGORY="base" fi echo ::set-output name=category::${CATEGORY} VERSION=$(cat ./.containers/${CATEGORY}/${{ matrix.container }}/VERSION) echo ::set-output name=version::${VERSION} PLATFORM="linux/amd64" echo ::set-output name=platform::${PLATFORM} if test -f "./.containers/${CATEGORY}/${{ matrix.container }}/goss.yaml"; then echo ::set-output name=goss::true else echo ::set-output name=goss::false fi if [ "${{github.event_name}}" == "pull_request" ]; then echo ::set-output name=push::false echo ::set-output name=cache_from::"type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:buildcache" || echo ::set-output name=cache_from::"" echo ::set-output name=cache_to::"" else echo ::set-output name=push::true echo ::set-output name=cache_from::"type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:buildcache" echo ::set-output name=cache_to::"type=registry,ref=ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:buildcache,mode=max" fi - name: Set up QEMU uses: docker/setup-qemu-action@v1 with: platforms: amd64 - name: Login to GHCR uses: docker/login-action@v1 if: github.event_name != 'pull_request' with: registry: ghcr.io username: ${{ secrets.GHCR_USERNAME }} password: ${{ secrets.GHCR_TOKEN }} # Install and configure Buildx - name: Set up Docker Buildx id: buildx uses: docker/setup-buildx-action@v1 with: install: true version: latest driver-opts: image=moby/buildkit:master # Install the GOSS testing framework - name: Set up goss/dgoss uses: e1himself/goss-installation-action@v1.0.3 if: ${{ steps.prep.outputs.goss == 'true' }} with: version: 'v0.3.16' # Creates a local build to run tests on - name: Build and Load local test-container if: ${{ steps.prep.outputs.goss == 'true' }} uses: docker/build-push-action@v2 with: build-args: VERSION=${{ steps.prep.outputs.version }} context: . file: ./.containers/${{ steps.prep.outputs.category }}/${{ matrix.container }}/Dockerfile load: true tags: | ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:test cache-from: ${{ steps.prep.outputs.cache_from }} cache-to: ${{ steps.prep.outputs.cache_to }} # Run GOSS tests if included with the container - name: Run GOSS tests if: ${{ steps.prep.outputs.goss == 'true' }} env: GOSS_FILE: ./.containers/${{ steps.prep.outputs.category }}/${{ matrix.container }}/goss.yaml run: | dgoss run ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:test # Push if not a PR, otherwise just test the build process for all requested platforms - name: Build and Push uses: docker/build-push-action@v2 with: build-args: VERSION=${{ steps.prep.outputs.version }} context: . platforms: ${{ steps.prep.outputs.platform }} file: ./.containers/${{ steps.prep.outputs.category }}/${{ matrix.container }}/Dockerfile push: ${{ steps.prep.outputs.push }} tags: | ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:latest ghcr.io/${{ github.repository_owner }}/${{ matrix.container }}:v${{ steps.prep.outputs.version }} cache-from: ${{ steps.prep.outputs.cache_from }} cache-to: ${{ steps.prep.outputs.cache_to }} container-build-complete: needs: [build] name: Container Build Completed runs-on: ubuntu-latest steps: - name: complete message run: echo "Container Build and Tests Completed Successfully"