Bootstrap toolchain and CI pipeline

This commit is contained in:
tyranron 2021-04-07 14:26:50 +03:00
parent 4f341d3428
commit 497be2cdd6
No known key found for this signature in database
GPG Key ID: 762E144FB230A4F0
3 changed files with 336 additions and 6 deletions

127
.github/workflows/docker.yml vendored Normal file
View File

@ -0,0 +1,127 @@
name: Docker CI
on:
pull_request:
push:
schedule:
- cron: '13 13 * * 3'
jobs:
buildx:
strategy:
matrix:
include:
- dockerfile: debian
cache: ${{ github.ref != 'refs/heads/master'
&& !startsWith(github.ref, 'refs/tags/docker/') }}
publish: ${{ github.event_name == 'push'
&& (startsWith(github.ref, 'refs/tags/docker/')
|| github.ref == 'refs/heads/master') }}
release: ${{ github.event_name == 'push'
&& startsWith(github.ref, 'refs/tags/docker/') }}
- dockerfile: alpine
cache: ${{ github.ref != 'refs/heads/master'
&& !startsWith(github.ref, 'refs/tags/docker/') }}
publish: ${{ github.event_name == 'push'
&& (startsWith(github.ref, 'refs/tags/docker/')
|| github.ref == 'refs/heads/master') }}
release: ${{ github.event_name == 'push'
&& startsWith(github.ref, 'refs/tags/docker/') }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: docker/setup-qemu-action@v1
- uses: docker/setup-buildx-action@v1
- name: Detect correct Git ref for image build
id: gitref
uses: actions/github-script@v3
with:
result-encoding: string
script: |
let ref = 'HEAD';
if ('${{ github.ref }}'.startsWith('refs/tags/docker/')) {
ref = '${{ github.ref }}'.substring(17).split('-')[0];
}
return ref;
- name: Pre-build fresh Docker images cache
run: make docker.build.cache no-cache=yes
DOCKERFILE=${{ matrix.dockerfile }}
ref=${{ steps.gitref.outputs.result }}
working-directory: ./docker/coturn
if: ${{ !matrix.cache }}
- uses: satackey/action-docker-layer-caching@v0.0.11
with:
key: docker-${{ matrix.dockerfile }}-buildx-{hash}
restore-keys: docker-${{ matrix.dockerfile }}-buildx-
continue-on-error: true
timeout-minutes: 10
if: ${{ matrix.cache }}
- name: Pre-build Docker images cache
run: make docker.build.cache no-cache=no
DOCKERFILE=${{ matrix.dockerfile }}
ref=${{ steps.gitref.outputs.result }}
working-directory: ./docker/coturn
if: ${{ matrix.cache }}
- name: Test Docker images
run: |
# Enable experimental features of Docker Daemon to run multi-arch images.
echo "$(cat /etc/docker/daemon.json)" '{"experimental": true}' \
| jq --slurp 'reduce .[] as $item ({}; . * $item)' \
| sudo tee /etc/docker/daemon.json
sudo systemctl restart docker
make npm.install
make test.docker platforms=@all build=yes DOCKERFILE=${{ matrix.dockerfile }}
working-directory: ./docker/coturn
- name: Login to GitHub Container Registry
uses: docker/login-action@v1
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GCR_BOT_PAT }}
if: ${{ matrix.publish }}
- name: Login to Quay.io
uses: docker/login-action@v1
with:
registry: quay.io
username: instrumentisto+bot
password: ${{ secrets.QUAYIO_ROBOT_TOKEN }}
if: ${{ matrix.publish }}
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: instrumentistobot
password: ${{ secrets.DOCKERHUB_BOT_PASS }}
if: ${{ matrix.publish }}
- run: make docker.push DOCKERFILE=${{ matrix.dockerfile }}
working-directory: ./docker/coturn
if: ${{ matrix.publish }}
# On GitHub Container Registry README is automatically updated on pushes.
- name: Update README on Quay.io
uses: christian-korneck/update-container-description-action@v1
env:
DOCKER_APIKEY: ${{ secrets.QUAYIO_API_TOKEN }}
with:
provider: quay
destination_container_repo: quay.io/coturn/coturn
readme_file: docker/coturn/README.md
if: ${{ matrix.publish }}
- name: Update README on Docker Hub
uses: christian-korneck/update-container-description-action@v1
env:
DOCKER_USER: ${{ secrets.DOCKERHUB_BOT_USER }}
DOCKER_PASS: ${{ secrets.DOCKERHUB_BOT_PASS }}
with:
provider: dockerhub
destination_container_repo: coturn/coturn
readme_file: docker/coturn/README.md
if: ${{ matrix.publish }}
#TODO: release

View File

@ -1,3 +1,164 @@
###############################
# Common defaults/definitions #
###############################
comma := ,
empty :=
space := $(empty) $(empty)
# Checks two given strings for equality.
eq = $(if $(or $(1),$(2)),$(and $(findstring $(1),$(2)),\
$(findstring $(2),$(1))),1)
######################
# Project parameters #
######################
COTURN_VER ?= 4.5.2
COTURN_MIN_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1,2))
COTURN_MAJ_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1))
BUILD_REV ?= 0
NAMESPACES := coturn \
ghcr.io/coturn
NAME := coturn
ALL_IMAGES := \
debian:$(COTURN_VER)-r$(BUILD_REV)-debian,$(COTURN_VER)-debian,$(COTURN_MIN_VER)-debian,$(COTURN_MAJ_VER)-debian,debian,$(COTURN_VER)-r$(BUILD_REV),$(COTURN_VER),$(COTURN_MIN_VER),$(COTURN_MAJ_VER),latest \
alpine:$(COTURN_VER)-r$(BUILD_REV)-alpine,$(COTURN_VER)-alpine,$(COTURN_MIN_VER)-alpine,$(COTURN_MAJ_VER)-alpine,alpine
# <Dockerfile>:<version>,<tag1>,<tag2>,...
# Default is first image from ALL_IMAGES list.
DOCKERFILE ?= $(word 1,$(subst :, ,$(word 1,$(ALL_IMAGES))))
TAGS ?= $(word 1,$(subst |, ,\
$(word 2,!$(subst $(DOCKERFILE):, ,$(subst $(space),|,$(ALL_IMAGES))))))
VERSION ?= $(word 1,$(subst -, ,$(TAGS)))-$(word 2,$(strip \
$(subst -, ,$(subst $(comma), ,$(TAGS)))))
PLATFORMS ?= linux/amd64 \
linux/arm64 \
linux/arm/v6 \
linux/arm/v7 \
linux/ppc64le \
linux/s390x
MAIN_PLATFORM ?= $(word 1,$(subst $(comma), ,$(PLATFORMS)))
###########
# Aliases #
###########
image: docker.image
push: docker.push
release: git.release
test: test.docker
###################
# Docker commands #
###################
docker-namespaces = $(strip $(if $(call eq,$(namespaces),),\
$(NAMESPACES),$(subst $(comma), ,$(namespaces))))
docker-tags = $(strip $(if $(call eq,$(tags),),\
$(TAGS),$(subst $(comma), ,$(tags))))
docker-platforms = $(strip $(if $(call eq,$(platforms),),\
$(PLATFORMS),$(subst $(comma), ,$(platforms))))
# Runs `docker buildx build` command allowing to customize it for the purpose of
# re-tagging or pushing.
define docker.buildx
$(eval dockerfile := $(strip $(1)))
$(eval namespace := $(strip $(2)))
$(eval tag := $(strip $(3)))
$(eval git-ref := $(strip $(4)))
$(eval platform := $(strip $(5)))
$(eval no-cache := $(strip $(6)))
$(eval args := $(strip $(7)))
cd ../../ && \
docker buildx build --force-rm $(args) \
--platform $(platform) \
$(if $(call eq,$(no-cache),yes),--no-cache --pull,) \
$(if $(call eq,$(git-ref),),,--build-arg git_ref=$(git-ref)) \
-f docker/coturn/$(dockerfile)/Dockerfile \
-t $(namespace)/$(NAME):$(tag) ./
endef
# Pre-build cache for Docker image builds.
#
# WARNING: This command doesn't apply tag to the built Docker image, just
# creates a build cache. To produce a Docker image with a tag, use
# `docker.tag` command right after running this one.
#
# Usage:
# make docker.build.cache [DOCKERFILE=(debian|alpine)]
# [platforms=($(PLATFORMS)|<platform-1>[,<platform-2>...])]
# [no-cache=(no|yes)]
# [ref=<git-ref>]
docker.build.cache:
$(call docker.buildx,$(DOCKERFILE),\
instrumentisto,\
build-cache,\
$(ref),\
$(shell echo "$(docker-platforms)" | tr -s '[:blank:]' ','),\
$(no-cache),\
--output 'type=image$(comma)push=false')
# Build Docker image on the given platform with the given tag.
#
# Usage:
# make docker.image [DOCKERFILE=(debian|alpine)]
# [tag=($(VERSION)|<tag>)]
# [platform=($(MAIN_PLATFORM)|<platform>)]
# [no-cache=(no|yes)]
# [ref=<git-ref>]
docker.image:
$(call docker.buildx,$(DOCKERFILE),\
instrumentisto,\
$(if $(call eq,$(tag),),$(VERSION),$(tag)),\
$(ref),\
$(if $(call eq,$(platform),),$(MAIN_PLATFORM),$(platform)),\
$(no-cache),\
--load)
# Push Docker images to their repositories (container registries),
# along with the required multi-arch manifests.
#
# Usage:
# make docker.push [DOCKERFILE=(debian|alpine)]
# [namespaces=($(NAMESPACES)|<prefix-1>[,<prefix-2>...])]
# [tags=($(TAGS)|<tag-1>[,<tag-2>...])]
# [platforms=($(PLATFORMS)|<platform-1>[,<platform-2>...])]
# [ref=<git-ref>]
docker.push:
$(foreach namespace,$(docker-namespaces),\
$(foreach tag,$(docker-tags),\
$(call docker.buildx,$(DOCKERFILE),\
$(namespace),\
$(tag),\
$(ref),\
$(shell echo "$(docker-platforms)" | tr -s '[:blank:]' ','),,\
--push)))
####################
# Testing commands #
####################
@ -8,17 +169,35 @@
# https://github.com/bats-core/bats-core
#
# Usage:
# make test.docker [tag=($(VERSION)|<tag>)]
# make test.docker
# [tag=($(VERSION)|<tag>)]
# [platforms=($(MAIN_PLATFORM)|@all|<platform-1>[,<platform-2>...])]
# [( [build=no]
# | build=yes [DOCKERFILE=(debian|alpine)]
# [ref=<git-ref>] )]
test-docker-platforms = $(strip $(if $(call eq,$(platforms),),$(MAIN_PLATFORM),\
$(if $(call eq,$(platforms),@all),$(PLATFORMS),\
$(docker-platforms))))
test.docker:
ifeq ($(wildcard node_modules/.bin/bats),)
@make npm.install
endif
DOCKERFILE=$(DOCKERFILE) \
IMAGE=coturn-debian \
$(foreach platform,$(test-docker-platforms),\
$(call test.docker.do,\
$(if $(call eq,$(tag),),$(VERSION),$(tag)),\
$(platform)))
define test.docker.do
$(eval tag := $(strip $(1)))
$(eval platform := $(strip $(2)))
$(if $(call eq,$(build),yes),\
@make docker.image DOCKERFILE=$(DOCKERFILE) \
no-cache=no tag=$(tag) platform=$(platform) ref=$(ref) ,)
IMAGE=instrumentisto/$(NAME):$(tag) PLATFORM=$(platform) \
node_modules/.bin/bats \
--timing $(if $(call eq,$(CI),),--pretty,--formatter tap) \
tests/main.bats
endef
@ -44,9 +223,33 @@ endif
################
# Git commands #
################
# Release project version (apply version tag and push).
#
# Usage:
# make git.release [ver=($(VERSION)|<proj-ver>)]
git-release-tag = docker/$(strip $(if $(call eq,$(ver),),$(VERSION),$(ver)))
git.release:
ifeq ($(shell git rev-parse $(git-release-tag) >/dev/null 2>&1 && echo "ok"),ok)
$(error "Git tag $(git-release-tag) already exists")
endif
git tag $(git-release-tag)
git push origin refs/tags/$(git-release-tag)
##################
# .PHONY section #
##################
.PHONY: npm.install \
.PHONY: image push release test \
docker.build.cache docker.image docker.push \
git.release \
npm.install \
test.docker

View File

@ -12,7 +12,7 @@
}
@test "Coturn has correct version" {
[ -z "$VERSION" ] && skip
[ -z "$COTURN_VER" ] && skip
run docker run --rm --entrypoint sh $IMAGE -c \
"turnserver -o --log-file=stdout | grep 'Version Coturn' \
@ -22,7 +22,7 @@
[ ! "$output" = '' ]
actual="$output"
[ "$actual" = "$VERSION" ]
[ "$actual" = "$COTURN_VER" ]
}