Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to GitHub Actions for CI #257

Merged
merged 5 commits into from
Oct 7, 2021
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
53 changes: 53 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -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 changes: 0 additions & 29 deletions .travis.yml

This file was deleted.

13 changes: 5 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand All @@ -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 changes: 2 additions & 22 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -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)


Expand Down
18 changes: 0 additions & 18 deletions ci/docker

This file was deleted.

4 changes: 3 additions & 1 deletion ci/docker-deb-test
Original file line number Diff line number Diff line change
@@ -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/
Expand Down
6 changes: 3 additions & 3 deletions ci/docker-python-test
Original file line number Diff line number Diff line change
@@ -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
12 changes: 0 additions & 12 deletions ci/docker-tox-test

This file was deleted.

2 changes: 1 addition & 1 deletion pytest.ini
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[pytest]
timeout = 5
timeout = 20
2 changes: 0 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from __future__ import print_function

import os.path
import subprocess
import tempfile
Expand Down
11 changes: 10 additions & 1 deletion testing/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 0 additions & 2 deletions testing/print_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
28 changes: 25 additions & 3 deletions tests/cli_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'
)
Expand All @@ -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
)
Expand All @@ -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'
Expand Down
14 changes: 10 additions & 4 deletions tests/cwd_test.py
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 changes: 3 additions & 3 deletions tox.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[tox]
envlist = py37,gcov
envlist = py38,gcov

[testenv]
deps = -r{toxinidir}/requirements-dev.txt
Expand All @@ -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]
Expand Down