Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
[run]
branch = true
data_file = ${COVERAGE_DATAFILE-.coverage}
include = snekbox/*
omit =
snekbox/api/app.py
Expand Down
96 changes: 96 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
on:
workflow_call:
outputs:
artifact:
description: The name of the uploaded image aretfact.
value: ${{ jobs.build.outputs.artifact }}
tag:
description: The tag used for the built image.
value: ${{ jobs.build.outputs.tag }}

jobs:
build:
name: Build snekbox-venv image
runs-on: ubuntu-latest
outputs:
artifact: ${{ env.artifact }}
tag: ${{ steps.sha_tag.outputs.tag }}
env:
artifact: image_artifact_snekbox-venv

steps:
# Create a short SHA with which to tag built images.
- name: Create SHA Container Tag
id: sha_tag
run: |
tag=$(cut -c 1-7 <<< $GITHUB_SHA)
echo "::set-output name=tag::$tag"

- name: Checkout code
uses: actions/checkout@v2

# The current version (v2) of Docker's build-push action uses buildx,
# which comes with BuildKit. It has cache features which can speed up
# the builds. See https://github.com/docker/build-push-action
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Log in to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

# The image built for PRs may start to deviate from the "latest" image
# currently in GHCR. Configure the subsequent build step to cache the
# layers in GitHub Actions for PRs.
# See https://github.com/moby/buildkit#github-actions-cache-experimental
#
# Because the cache is scoped to the branch, it will not be available
# on the main branch when the PR is merged. Furthermore, using this cache
# on main is redundant since the previous build's images are already
# cached on GHCR. Thus, this step is only used for PRs.
- name: Configure cache
id: cache_config
run: |
set -eu
if [ "$GITHUB_EVENT_NAME" = 'pull_request' ]; then
cache_from="type=gha,scope=buildkit-${GITHUB_REF}"
cache_to="${cache_from},mode=max"
fi
echo "::set-output name=cache_from::${cache_from:-}"
echo "::set-output name=cache_to::${cache_to:-}"

# Build the "DEV" version of the image, which targets the `venv` stage
# and includes development dependencies.
#
# Include an inline cache manifest in the image to support caching from
# GHCR. This enables subsequent builds to pull reusable layers from GHCR.
# If configured by the cache_config step, also cache the layers in
# GitHub Actions.
- name: Build image for linting and testing
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: false
target: venv
build-args: DEV=1
outputs: type=docker,dest=${{ env.artifact }}.tar
cache-from: |
${{ steps.cache_config.outputs.cache_from }}
ghcr.io/python-discord/snekbox-base:latest
ghcr.io/python-discord/snekbox-venv:latest
cache-to: ${{ steps.cache_config.outputs.cache_to }}
tags: ghcr.io/python-discord/snekbox-venv:${{ steps.sha_tag.outputs.tag }}

# Make the image available as an artifact so other jobs will be able to
# download it.
- name: Upload image archive as an artifact
uses: actions/upload-artifact@v2
with:
name: ${{ env.artifact }}
path: ${{ env.artifact }}.tar
retention-days: 1 # It's only needed for the duration of the workflow.
if-no-files-found: error
96 changes: 96 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
on:
workflow_call:
inputs:
artifact:
required: true
type: string
tag:
required: true
type: string

jobs:
deploy:
name: Build, push, & deploy
runs-on: ubuntu-latest

steps:
- name: Download image artifact
uses: actions/download-artifact@v2
with:
name: ${{ inputs.artifact }}

# Load the image to make use of common layers during the final build.
- name: Load image from archive
run: docker load -i ${{ inputs.artifact }}.tar

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1

- name: Log in to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

# The Dockerfile will be needed.
- name: Checkout code
uses: actions/checkout@v2

# Build the final production image and push it to GHCR.
# Tag it with both the short commit SHA and 'latest'.
- name: Build final image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
push: true
cache-from: |
ghcr.io/python-discord/snekbox-base:latest
ghcr.io/python-discord/snekbox-venv:latest
ghcr.io/python-discord/snekbox:latest
cache-to: type=inline
tags: |
ghcr.io/python-discord/snekbox:latest
ghcr.io/python-discord/snekbox:${{ inputs.tag }}
build-args: git_sha=${{ github.sha }}

# Deploy to Kubernetes.
- name: Authenticate with Kubernetes
uses: azure/k8s-set-context@v1
with:
method: kubeconfig
kubeconfig: ${{ secrets.KUBECONFIG }}

- name: Deploy to Kubernetes
uses: Azure/k8s-deploy@v1
with:
manifests: deployment.yaml
images: 'ghcr.io/python-discord/snekbox:${{ inputs.tag }}'
kubectl-version: 'latest'

# Push the base image to GHCR, with an inline cache manifest.
- name: Push base image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
target: base
push: true
cache-from: ghcr.io/python-discord/snekbox-base:latest
cache-to: type=inline
tags: ghcr.io/python-discord/snekbox-base:latest

# Push the venv image to GHCR, with an inline cache manifest.
- name: Push venv image
uses: docker/build-push-action@v2
with:
context: .
file: ./Dockerfile
target: venv
push: true
cache-from: |
ghcr.io/python-discord/snekbox-base:latest
ghcr.io/python-discord/snekbox-venv:latest
cache-to: type=inline
tags: ghcr.io/python-discord/snekbox-venv:latest
Loading