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 <ed.smith@collabora.com>
Signed-off-by: Christopher Obbard <chris.obbard@collabora.com>
This commit is contained in:
Christopher Obbard
2021-08-06 17:00:12 +01:00
committed by Sjoerd Simons
parent b324040f0f
commit e4dfbfa557
6 changed files with 251 additions and 31 deletions

1
.dockerignore Normal file
View File

@@ -0,0 +1 @@
.git

View File

@@ -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

244
.github/workflows/ci.yaml vendored Normal file
View File

@@ -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

View File

@@ -5,7 +5,8 @@ services:
build:
context: ..
dockerfile: docker/Dockerfile
target: runner
image:
debos
volumes:
- type: bind
source: ../tests

View File

@@ -5,7 +5,8 @@ services:
build:
context: ..
dockerfile: docker/Dockerfile
target: runner
image:
debos
volumes:
- type: bind
source: ../tests

View File

@@ -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 ./...