Merge pull request #257 from chriskuehl/github-actions
Switch to GitHub Actions for CI
This commit is contained in:
commit
aae8d155f1
16 changed files with 115 additions and 110 deletions
53
.github/workflows/ci.yaml
vendored
Normal file
53
.github/workflows/ci.yaml
vendored
Normal file
|
@ -0,0 +1,53 @@
|
|||
name: CI
|
||||
on: push
|
||||
jobs:
|
||||
build-and-test:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- arch: amd64
|
||||
docker_image: debian:buster
|
||||
|
||||
- arch: arm64
|
||||
docker_image: arm64v8/debian:buster
|
||||
|
||||
- arch: ppc64le
|
||||
docker_image: ppc64le/debian:buster
|
||||
|
||||
- arch: s390x
|
||||
docker_image: s390x/debian:buster
|
||||
|
||||
env:
|
||||
BASE_IMAGE: ${{ matrix.docker_image }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
id: qemu
|
||||
uses: docker/setup-qemu-action@v1
|
||||
if: ${{ matrix.arch != 'amd64' }}
|
||||
with:
|
||||
image: tonistiigi/binfmt:latest
|
||||
|
||||
- name: Build Docker image
|
||||
run: make docker-image
|
||||
|
||||
- name: Run python tests
|
||||
run: docker run --rm -v $(pwd):/mnt:rw dumb-init-build /mnt/ci/docker-python-test
|
||||
|
||||
- name: Build Debian package
|
||||
run: docker run --init --rm -v $(pwd):/mnt:rw dumb-init-build make -C /mnt builddeb
|
||||
|
||||
- name: Test built Debian package
|
||||
# XXX: This uses the clean base image (not the build one) to make
|
||||
# sure it installs in a clean image without any hidden dependencies.
|
||||
run: docker run --rm -v $(pwd):/mnt:rw ${{ matrix.docker_image }} /mnt/ci/docker-deb-test
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: ${{ matrix.arch }}
|
||||
path: dist
|
29
.travis.yml
29
.travis.yml
|
@ -1,29 +0,0 @@
|
|||
language: c
|
||||
services:
|
||||
- docker
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- env: ITEST_TARGET=itest_focal
|
||||
- env: ITEST_TARGET=itest_buster
|
||||
- env: ITEST_TARGET=itest_tox
|
||||
- arch: ppc64le
|
||||
env: ITEST_TARGET=itest_buster
|
||||
- arch: arm64
|
||||
env: ITEST_TARGET=itest_buster
|
||||
- arch: s390x
|
||||
env: ITEST_TARGET=itest_buster
|
||||
allow_failures:
|
||||
- arch: ppc64le
|
||||
env: ITEST_TARGET=itest_buster
|
||||
- arch: arm64
|
||||
env: ITEST_TARGET=itest_buster
|
||||
- arch: s390x
|
||||
env: ITEST_TARGET=itest_buster
|
||||
|
||||
|
||||
script:
|
||||
- make "$ITEST_TARGET"
|
||||
|
||||
after_script:
|
||||
- ci/artifact-upload
|
13
Dockerfile
13
Dockerfile
|
@ -1,12 +1,8 @@
|
|||
FROM debian:buster
|
||||
ARG BASE_IMAGE=debian:buster
|
||||
FROM $BASE_IMAGE
|
||||
|
||||
LABEL maintainer="Chris Kuehl <ckuehl@yelp.com>"
|
||||
|
||||
# The default mirrors are too flaky to run reliably in CI.
|
||||
RUN sed -E \
|
||||
'/security\.debian/! s@http://[^/]+/@http://mirrors.kernel.org/@' \
|
||||
-i /etc/apt/sources.list
|
||||
|
||||
# Install the bare minimum dependencies necessary for working with Debian
|
||||
# packages. Build dependencies should be added under "Build-Depends" inside
|
||||
# debian/control instead.
|
||||
|
@ -17,6 +13,9 @@ RUN : \
|
|||
devscripts \
|
||||
equivs \
|
||||
lintian \
|
||||
python3-distutils \
|
||||
python3-setuptools \
|
||||
python3-pip \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
WORKDIR /tmp/mnt
|
||||
|
@ -27,5 +26,3 @@ RUN : \
|
|||
&& mk-build-deps --install --tool 'apt-get -y --no-install-recommends' /control \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
ENTRYPOINT make builddeb
|
||||
|
|
24
Makefile
24
Makefile
|
@ -54,11 +54,11 @@ builddeb:
|
|||
.PHONY: builddeb-docker
|
||||
builddeb-docker: docker-image
|
||||
mkdir -p dist
|
||||
docker run --user $$(id -u):$$(id -g) -v $(PWD):/tmp/mnt dumb-init-build
|
||||
docker run --init --user $$(id -u):$$(id -g) -v $(PWD):/tmp/mnt dumb-init-build make builddeb
|
||||
|
||||
.PHONY: docker-image
|
||||
docker-image:
|
||||
docker build -t dumb-init-build .
|
||||
docker build $(if $(BASE_IMAGE),--build-arg BASE_IMAGE=$(BASE_IMAGE)) -t dumb-init-build .
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
|
@ -68,23 +68,3 @@ test:
|
|||
.PHONY: install-hooks
|
||||
install-hooks:
|
||||
tox -e pre-commit -- install -f --install-hooks
|
||||
|
||||
ITEST_TARGETS = itest_focal itest_buster
|
||||
|
||||
.PHONY: itest $(ITEST_TARGETS)
|
||||
itest: $(ITEST_TARGETS)
|
||||
|
||||
itest_focal: _itest-ubuntu-focal
|
||||
itest_buster: _itest-debian-buster
|
||||
|
||||
itest_tox:
|
||||
$(DOCKER_RUN_TEST) debian:buster /mnt/ci/docker-tox-test
|
||||
|
||||
_itest-%: _itest_deb-% _itest_python-%
|
||||
@true
|
||||
|
||||
_itest_python-%:
|
||||
$(DOCKER_RUN_TEST) $(shell sed 's/-/:/' <<< "$*") /mnt/ci/docker-python-test
|
||||
|
||||
_itest_deb-%: builddeb-docker
|
||||
$(DOCKER_RUN_TEST) $(shell sed 's/-/:/' <<< "$*") /mnt/ci/docker-deb-test
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
dumb-init
|
||||
========
|
||||
|
||||
[![Travis CI](https://travis-ci.org/Yelp/dumb-init.svg?branch=master)](https://travis-ci.org/Yelp/dumb-init/)
|
||||
[![PyPI version](https://badge.fury.io/py/dumb-init.svg)](https://pypi.python.org/pypi/dumb-init)
|
||||
|
||||
|
||||
|
|
18
ci/docker
18
ci/docker
|
@ -1,18 +0,0 @@
|
|||
# The default mirrors are too flaky to run reliably in CI.
|
||||
sed -E \
|
||||
'/security\.debian/! s@http://[^/]+/@http://mirrors.kernel.org/@' \
|
||||
-i /etc/apt/sources.list
|
||||
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
build-essential \
|
||||
procps \
|
||||
python3 \
|
||||
python3-dev \
|
||||
python3-pip \
|
||||
python3-setuptools
|
||||
|
||||
cp -r /mnt/ /test
|
||||
cd /test
|
||||
|
||||
# vim: ft=sh
|
|
@ -1,8 +1,10 @@
|
|||
#!/bin/bash -eux
|
||||
set -o pipefail
|
||||
|
||||
. /mnt/ci/docker
|
||||
apt-get update
|
||||
apt-get -y --no-install-recommends install python3-pip procps
|
||||
|
||||
cd /mnt
|
||||
dpkg -i dist/*.deb
|
||||
pip3 install -r requirements-dev.txt
|
||||
pytest tests/
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/bin/bash -eux
|
||||
set -o pipefail
|
||||
set -euo pipefail
|
||||
|
||||
. /mnt/ci/docker
|
||||
cd /mnt
|
||||
|
||||
python3 setup.py clean
|
||||
python3 setup.py sdist
|
||||
pip3 install -vv dist/*.tar.gz
|
||||
pip3 install -r requirements-dev.txt
|
||||
pytest tests/
|
||||
pytest-3 -vv tests/
|
||||
|
||||
exec dumb-init /mnt/tests/test-zombies
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
#!/bin/bash -eux
|
||||
set -o pipefail
|
||||
|
||||
. /mnt/ci/docker
|
||||
|
||||
apt-get update
|
||||
apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
python3.7-dev \
|
||||
tox
|
||||
|
||||
tox
|
|
@ -1,2 +1,2 @@
|
|||
[pytest]
|
||||
timeout = 5
|
||||
timeout = 20
|
||||
|
|
2
setup.py
2
setup.py
|
@ -1,5 +1,3 @@
|
|||
from __future__ import print_function
|
||||
|
||||
import os.path
|
||||
import subprocess
|
||||
import tempfile
|
||||
|
|
|
@ -52,7 +52,16 @@ def child_pids(pid):
|
|||
for p in LocalPath('/proc').listdir():
|
||||
try:
|
||||
stat = open(p.join('stat').strpath).read()
|
||||
m = re.match(r'^\d+ \(.+?\) [a-zA-Z] (\d+) ', stat)
|
||||
m = re.match(
|
||||
r'^\d+ \(.+?\) '
|
||||
# This field, state, is normally a single letter, but can be
|
||||
# "0" if there are some unusual security settings that prevent
|
||||
# reading the process state (happens under GitHub Actions with
|
||||
# QEMU for some reason).
|
||||
'[0a-zA-Z] '
|
||||
r'(\d+) ',
|
||||
stat,
|
||||
)
|
||||
assert m, stat
|
||||
ppid = int(m.group(1))
|
||||
if ppid == pid:
|
||||
|
|
|
@ -4,8 +4,6 @@
|
|||
Since all signals are printed and otherwise ignored, you'll need to send
|
||||
SIGKILL (kill -9) to this process to actually end it.
|
||||
"""
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import signal
|
||||
import sys
|
||||
|
|
|
@ -12,12 +12,34 @@ def current_version():
|
|||
return open('VERSION').read().strip()
|
||||
|
||||
|
||||
def normalize_stderr(stderr):
|
||||
# dumb-init prints out argv[0] in its usage message. This should always be
|
||||
# just "dumb-init" under regular test scenarios here since that is how we
|
||||
# call it, but in CI the use of QEMU causes the argv[0] to be replaced with
|
||||
# the full path.
|
||||
#
|
||||
# This is supposed to be avoidable by:
|
||||
# 1) Setting the "P" flag in the binfmt register:
|
||||
# https://en.wikipedia.org/wiki/Binfmt_misc#Registration
|
||||
# This can be done by setting the QEMU_PRESERVE_PARENT env var when
|
||||
# calling binfmt.
|
||||
#
|
||||
# 2) Setting the "QEMU_ARGV0" env var to empty string for *all*
|
||||
# processes:
|
||||
# https://bugs.launchpad.net/qemu/+bug/1835839
|
||||
#
|
||||
# I can get it working properly in CI outside of Docker, but for some
|
||||
# reason not during Docker builds. This doesn't affect the built executable
|
||||
# so I decided to just punt on it.
|
||||
return re.sub(rb'(^|(?<=\s))[a-z/.]+/dumb-init', b'dumb-init', stderr)
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('both_debug_modes', 'both_setsid_modes')
|
||||
def test_no_arguments_prints_usage():
|
||||
proc = Popen(('dumb-init'), stderr=PIPE)
|
||||
_, stderr = proc.communicate()
|
||||
assert proc.returncode != 0
|
||||
assert stderr == (
|
||||
assert normalize_stderr(stderr) == (
|
||||
b'Usage: dumb-init [option] program [args]\n'
|
||||
b'Try dumb-init --help for full usage.\n'
|
||||
)
|
||||
|
@ -28,7 +50,7 @@ def test_exits_invalid_with_invalid_args():
|
|||
proc = Popen(('dumb-init', '--yolo', '/bin/true'), stderr=PIPE)
|
||||
_, stderr = proc.communicate()
|
||||
assert proc.returncode == 1
|
||||
assert stderr in (
|
||||
assert normalize_stderr(stderr) in (
|
||||
b"dumb-init: unrecognized option '--yolo'\n", # glibc
|
||||
b'dumb-init: unrecognized option: yolo\n', # musl
|
||||
)
|
||||
|
@ -43,7 +65,7 @@ def test_help_message(flag, current_version):
|
|||
proc = Popen(('dumb-init', flag), stderr=PIPE)
|
||||
_, stderr = proc.communicate()
|
||||
assert proc.returncode == 0
|
||||
assert stderr == (
|
||||
assert normalize_stderr(stderr) == (
|
||||
b'dumb-init v' + current_version.encode('ascii') + b'\n'
|
||||
b'Usage: dumb-init [option] command [[arg] ...]\n'
|
||||
b'\n'
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import os
|
||||
import shutil
|
||||
from subprocess import run, PIPE
|
||||
from subprocess import PIPE
|
||||
from subprocess import run
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
@pytest.mark.usefixtures('both_debug_modes', 'both_setsid_modes')
|
||||
def test_working_directories():
|
||||
"""The child process must start in the working directory in which
|
||||
|
@ -14,9 +16,13 @@ def test_working_directories():
|
|||
# predictable output - so we can't rely on dumb-init being found
|
||||
# in the "." directory.
|
||||
dumb_init = os.path.realpath(shutil.which('dumb-init'))
|
||||
proc = run((dumb_init,
|
||||
'sh', '-c', 'readlink /proc/$PPID/cwd && readlink /proc/$$/cwd'),
|
||||
cwd="/tmp", stdout=PIPE, stderr=PIPE)
|
||||
proc = run(
|
||||
(
|
||||
dumb_init,
|
||||
'sh', '-c', 'readlink /proc/$PPID/cwd && readlink /proc/$$/cwd',
|
||||
),
|
||||
cwd='/tmp', stdout=PIPE, stderr=PIPE,
|
||||
)
|
||||
|
||||
assert proc.returncode == 0
|
||||
assert proc.stdout == b'/\n/tmp\n'
|
||||
|
|
6
tox.ini
6
tox.ini
|
@ -1,5 +1,5 @@
|
|||
[tox]
|
||||
envlist = py37,gcov
|
||||
envlist = py38,gcov
|
||||
|
||||
[testenv]
|
||||
deps = -r{toxinidir}/requirements-dev.txt
|
||||
|
@ -8,14 +8,14 @@ commands =
|
|||
|
||||
[testenv:gcov]
|
||||
skip_install = True
|
||||
basepython = /usr/bin/python3.7
|
||||
basepython = /usr/bin/python3.8
|
||||
commands =
|
||||
{toxinidir}/ci/gcov-build {envbindir}
|
||||
{[testenv]commands}
|
||||
{toxinidir}/ci/gcov-report
|
||||
|
||||
[testenv:pre-commit]
|
||||
basepython = /usr/bin/python3.7
|
||||
basepython = /usr/bin/python3.8
|
||||
commands = pre-commit {posargs:run --all-files}
|
||||
|
||||
[flake8]
|
||||
|
|
Loading…
Reference in a new issue