From e4dfbfa55778fce04b59c48751b562b0e28c63f5 Mon Sep 17 00:00:00 2001 From: Christopher Obbard Date: Fri, 6 Aug 2021 17:00:12 +0100 Subject: [PATCH] Build docker container in GitHub actions This is a continuation of work done by @eds-collabora in !275 This replaces the old, simpler pipeline with a three phase process: - First, build the image and cache it using docker buildx. - Second, run all the tests in parallel, restoring the image from the cache. - Thirdly, if the tests pass: - if this is a push to the main branch, push to DockerHub. - push to GitHub Container registry (PS: will push to a user's own fork). This uses Buildkit caching aggressively, and will make use of the entire 5GiB allocation of cache space that GitHub provides over time. It requires the following additional repository secrets: - DOCKERHUB_USERNAME: the username to login as on DockerHub (e.g. go-debos) - DOCKERHUB_PASSWORD: an access token for the DockerHub repository. Closes: #275 Based on original work by: Ed Smith Signed-off-by: Christopher Obbard --- .dockerignore | 1 + .github/workflows/build-test.yaml | 29 ---- .github/workflows/ci.yaml | 244 ++++++++++++++++++++++++++++++ docker/recipes-test-uml.yml | 3 +- docker/recipes.test.yml | 3 +- docker/unit-tests.test.yml | 2 + 6 files changed, 251 insertions(+), 31 deletions(-) create mode 100644 .dockerignore delete mode 100644 .github/workflows/build-test.yaml create mode 100644 .github/workflows/ci.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..6b8710a --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +.git diff --git a/.github/workflows/build-test.yaml b/.github/workflows/build-test.yaml deleted file mode 100644 index c94537c..0000000 --- a/.github/workflows/build-test.yaml +++ /dev/null @@ -1,29 +0,0 @@ -name: Build Debos and run tests -on: [pull_request, push] - -jobs: - build-test: - name: Build Debos and run tests - runs-on: ubuntu-latest - steps: - - name: Repository checkout - uses: actions/checkout@v3 - - - name: Build container - run: | - docker build -f docker/Dockerfile -t godebos/debos . - - - name: Run unit tests - run: | - docker-compose -f docker/unit-tests.test.yml \ - up --build --exit-code-from=sut - - - name: Run test recipes on host - run: | - docker-compose -f docker/recipes.test.yml \ - up --build --exit-code-from=sut - - - name: Run test recipes using UML backend - run: | - docker-compose -f docker/recipes-test-uml.yml \ - up --build --exit-code-from=sut diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 0000000..8157d74 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,244 @@ +name: Build and Test + +env: + GITHUB_TAG: ghcr.io/${{ github.repository }} + DOCKERHUB_TAG: godebos/debos + +on: + - push + - pull_request + - workflow_dispatch + +jobs: + build: + name: Build Docker container + runs-on: ubuntu-latest + steps: + - name: Repository checkout + uses: actions/checkout@v2 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: false + file: docker/Dockerfile + cache-to: type=local,dest=/tmp/.build-cache,mode=max + + unit-tests: + name: Run unit tests + needs: + - build + runs-on: ubuntu-latest + steps: + - name: Repository checkout + uses: actions/checkout@v2 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: false + tags: debos-builder + file: docker/Dockerfile + cache-from: type=local,src=/tmp/.build-cache + load: true + target: builder + + - name: Run unit tests + run: | + docker-compose -f docker/unit-tests.test.yml \ + up --exit-code-from=sut + + recipe-tests: + name: Run recipe tests + needs: + - build + runs-on: ubuntu-latest + steps: + - name: Repository checkout + uses: actions/checkout@v2 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: false + tags: debos + file: docker/Dockerfile + cache-from: type=local,src=/tmp/.build-cache + load: true + + - name: Run test recipes on host + run: | + docker-compose -f docker/recipes.test.yml \ + up --exit-code-from=sut + + uml-tests: + name: Run UML tests + needs: + - build + runs-on: ubuntu-latest + steps: + - name: Repository checkout + uses: actions/checkout@v2 + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: false + tags: debos + file: docker/Dockerfile + cache-from: type=local,src=/tmp/.build-cache + load: true + + - name: Run test recipes using UML backend + run: | + docker-compose -f docker/recipes-test-uml.yml \ + up --exit-code-from=sut + + publish-github: + name: Publish to GHCR + needs: + - unit-tests + - recipe-tests + - uml-tests + if: github.event_name != 'pull_request' + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ env.GITHUB_TAG }} + tags: | + "type=ref,event=branch" + "type=ref,suffix=-{{sha}},event=branch" + "type=ref,suffix=-{{date 'YYYYMMDD'}},event=branch" + "type=ref,event=tag" + "type=ref,event=pr" + + - name: Login to GitHub Container Registry + uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build and push Docker image + uses: docker/build-push-action@v2 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + file: docker/Dockerfile + cache-from: type=local,src=/tmp/.build-cache + + publish-dockerhub: + name: Publish to DockerHub + needs: + - unit-tests + - recipe-tests + - uml-tests + if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch) + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: ${{ env.DOCKERHUB_TAG }} + tags: | + "type=ref,event=branch" + "type=ref,suffix=-{{sha}},event=branch" + "type=ref,suffix=-{{date 'YYYYMMDD'}},event=branch" + "type=ref,event=tag" + "type=ref,event=pr" + + - name: Login to DockerHub + uses: docker/login-action@v1 + continue-on-error: true + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_PASSWORD }} + + - name: Setup Docker buildx + uses: docker/setup-buildx-action@v1 + + - name: Use cache + uses: actions/cache@v2 + with: + path: /tmp/.build-cache + key: ${{ runner.os }}-docker-${{ github.sha }} + + - name: Build and push Docker image + uses: docker/build-push-action@v2 + continue-on-error: true + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} + file: docker/Dockerfile + cache-from: type=local,src=/tmp/.build-cache diff --git a/docker/recipes-test-uml.yml b/docker/recipes-test-uml.yml index ff28598..75cd7a3 100644 --- a/docker/recipes-test-uml.yml +++ b/docker/recipes-test-uml.yml @@ -5,7 +5,8 @@ services: build: context: .. dockerfile: docker/Dockerfile - target: runner + image: + debos volumes: - type: bind source: ../tests diff --git a/docker/recipes.test.yml b/docker/recipes.test.yml index d10cb74..557738d 100644 --- a/docker/recipes.test.yml +++ b/docker/recipes.test.yml @@ -5,7 +5,8 @@ services: build: context: .. dockerfile: docker/Dockerfile - target: runner + image: + debos volumes: - type: bind source: ../tests diff --git a/docker/unit-tests.test.yml b/docker/unit-tests.test.yml index 3eaec86..5550543 100644 --- a/docker/unit-tests.test.yml +++ b/docker/unit-tests.test.yml @@ -6,5 +6,7 @@ services: context: .. dockerfile: docker/Dockerfile target: builder + image: + debos-builder working_dir: /usr/local/go/src/github.com/go-debos/debos command: go test -v ./...