diff --git a/.travis.yml b/.travis.yml index 83eae7c..207777e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,33 +4,11 @@ services: - docker env: - - VERSION=0.8.0 - - VERSION=0.8.1 - - VERSION=0.8.2 - - VERSION=0.8.3 - - VERSION=0.8.4 - - VERSION=0.8.5 - - VERSION=0.8.6 - - VERSION=0.9.0 - - VERSION=0.9.1 - - VERSION=0.9.2 - - VERSION=0.9.3 - - VERSION=0.9.4 + - VERSION=1.0.0 - VERSION=edge matrix: exclude: - - evn: VERSION=0.8.0 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.1 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.2 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.3 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.4 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.5 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.8.6 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.9.0 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.9.1 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.9.2 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.9.3 TRAVIS_EVENT_TYPE=cron - - evn: VERSION=0.9.4 TRAVIS_EVENT_TYPE=cron + - evn: VERSION=1.0.0 TRAVIS_EVENT_TYPE=cron allow_failures: - env: VERSION=edge diff --git a/build b/build index babd2d7..c64c95c 100755 --- a/build +++ b/build @@ -3,22 +3,15 @@ build() { declare build_files="${*:-versions/**/options}" - [[ "$BUILDER_IMAGE" ]] || { - BUILDER_IMAGE="phan-builder" - docker build -t "$BUILDER_IMAGE" builder - } - for file in $build_files; do ( source "$file" local version_dir version_dir="$(dirname "$file")" : "${TAGS:?}" "${BUILD_OPTIONS:?}" "${RELEASE:?}" - docker run -e "TRACE=$TRACE" --rm "$BUILDER_IMAGE" "${BUILD_OPTIONS[@]}" \ - > "$version_dir/rootfs.tar.gz" for tag in "${TAGS[@]}"; do - docker build -t "$tag" "$version_dir" + docker build ${BUILD_OPTIONS[@]} -t "$tag" "$version_dir" done ) done @@ -62,6 +55,7 @@ new_version() { sed "s:{{.VERSION}}:${version}:g;s:{{.AST}}:${ast}:g"<"$file">"versions/${version}/$(basename "$file")" ) done + chmod +x "versions/${version}/docker-entrypoint.sh" sed "s:{{.VERSION}}:${version}:g"<"templates/test/test_cloudflare_phan.bats">"test/test_cloudflare_phan-${version}.bats" } diff --git a/builder/Dockerfile b/builder/Dockerfile deleted file mode 100644 index 9901d93..0000000 --- a/builder/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM alpine:3.3 -COPY scripts/mkimage-phan.bash / -COPY scripts/docker-entrypoint.sh / -RUN apk --no-cache add bash -RUN apk --no-cache add --repository http://dl-cdn.alpinelinux.org/alpine/edge/community/ tini -ENTRYPOINT ["/sbin/tini", "-g", "--", "/mkimage-phan.bash"] diff --git a/builder/README.md b/builder/README.md deleted file mode 100644 index f06c5fa..0000000 --- a/builder/README.md +++ /dev/null @@ -1,16 +0,0 @@ -# Docker Phan rootfs Builder - -This builder image constructs a `rootfs.tar.gz` that is applied on a base Alpine -Linux image to build Phan images. The `mkimage-phan.bash` script does all -of the heavy lifting. During the configuration of the image the entrypoint is -added to the image. - -## Options - -The builder takes several options: - - * `-r `: The phan release tag to use (such `0.2`) or the special - `edge` to build the tip of master. - * `-m `: The Alpine Linux mirror base. Defaults to - `http://nl.alpinelinux.org/alpine`. - * `-s`: Outputs the `rootfs.tar.gz` to stdout. diff --git a/builder/scripts/mkimage-phan.bash b/builder/scripts/mkimage-phan.bash deleted file mode 100755 index 38967a4..0000000 --- a/builder/scripts/mkimage-phan.bash +++ /dev/null @@ -1,93 +0,0 @@ -#!/usr/bin/env bash - -# This mkimage-phan.bash is a modified version from -# https://github.com/gliderlabs/docker-alpine/blob/master/builder/scripts/mkimage-alpine.bash. - -declare REL="${REL:-edge}" -declare MIRROR="${MIRROR:-http://nl.alpinelinux.org/alpine}" -declare AST="${AST:-0.1.5}" - -set -eo pipefail; [[ "$TRACE" ]] && set -x - -build() { - declare mirror="$1" rel="$2" ast="$3" - - # configure rootfs - local rootfs - rootfs="$(mktemp -d "${TMPDIR:-/var/tmp}/docker-phan-rootfs-XXXXXXXXXX")" - mkdir -p "$rootfs/etc/apk/" - - # configure apk mirror - { - echo "$mirror/edge/main" - echo "$mirror/edge/community" - } | tee "/etc/apk/repositories" "$rootfs/etc/apk/repositories" >&2 - - # install PHP7 dependencies and build dependencies - { - apk --no-cache add php7 php7-json php7-sqlite3 php7-mbstring git build-base autoconf curl php7-dev php7-openssl php7-phar php7-dom - } >&2 - - - # install composer - { - cd /tmp - curl -O https://getcomposer.org/download/1.5.1/composer.phar - printf "2745e7b8cced2e97f84b9e9cb0f9c401702f47cecea5a67f095ac4fa1a44fb80 composer.phar" | sha256sum -c - mv composer.phar /usr/local/bin - } >&2 - - # install runtime dependencies into rootfs - { - apk --no-cache --root "$rootfs" --keys-dir /etc/apk/keys add --initdb php7 php7-json php7-sqlite3 php7-mbstring php7-pcntl php7-dom tini - cp /docker-entrypoint.sh "$rootfs"/docker-entrypoint.sh - } >&2 - - # install phan - mkdir -p "$rootfs/opt/" - { - cd "$rootfs/opt/" - if [[ "$rel" == "edge" ]]; then - git clone --single-branch --depth 1 https://github.com/phan/phan.git - else - git clone -b $rel --single-branch --depth 1 https://github.com/phan/phan.git - fi - cd phan - - php7 /usr/local/bin/composer.phar --prefer-dist --no-dev --ignore-platform-reqs --no-interaction install - rm -rf .git - } >&2 - - # install php-ast - { - cd /tmp - git clone -b "v${ast}" --single-branch --depth 1 https://github.com/nikic/php-ast.git - cd php-ast - phpize7 - ./configure --with-php-config=php-config7 - make INSTALL_ROOT="$rootfs" install - - printf "extension=ast.so" >> "$rootfs"/etc/php7/php.ini - } >&2 - - - tar -z -f rootfs.tar.gz --numeric-owner -C "$rootfs" -c . - [[ "$STDOUT" ]] && cat rootfs.tar.gz - - return 0 -} - -main() { - while getopts "a:r:m:s" opt; do - case $opt in - r) REL="$OPTARG";; - a) AST="$OPTARG";; - m) MIRROR="$OPTARG";; - s) STDOUT=1;; - esac - done - - build "$MIRROR" "$REL" "$AST" -} - -main "$@" diff --git a/templates/test/test_cloudflare_phan.bats b/templates/test/test_cloudflare_phan.bats index bd86f07..d14be9a 100644 --- a/templates/test/test_cloudflare_phan.bats +++ b/templates/test/test_cloudflare_phan.bats @@ -24,8 +24,8 @@ setup() { [ $status -eq 1 ] [ ${#lines[@]} -eq 2 ] - [ "${lines[0]}" = "./undefined_class.php:3 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Stub" ] - [ "${lines[1]}" = "./undefined_class.php:4 PhanUndeclaredClassConstant Reference to constant TYPE_STRING from undeclared class \Stub" ] + [ "${lines[0]}" = "undefined_class.php:3 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Stub" ] + [ "${lines[1]}" = "undefined_class.php:4 PhanUndeclaredClassConstant Reference to constant TYPE_STRING from undeclared class \Stub" ] } @test "checkstyle output format is available" { diff --git a/templates/versions/Dockerfile b/templates/versions/Dockerfile index 9812793..22606df 100644 --- a/templates/versions/Dockerfile +++ b/templates/versions/Dockerfile @@ -1,3 +1,80 @@ -FROM alpine:3.3 -ADD rootfs.tar.gz / +ARG ALPINE_VERSION=3.8 +ARG APK_MIRROR="http://nl.alpinelinux.org/alpine" +ARG AST_VERSION=0.1.5 +ARG PHAN_RELEASE="edge" + +# Baseline +# ========== +FROM alpine:$ALPINE_VERSION AS base + +# configure apk mirror +RUN echo "$APK_MIRROR/edge/main" >> "/etc/apk/repositories" \ + && echo "$APK_MIRROR/edge/community" >> "/etc/apk/repositories" + +# install runtime dependencies +RUN apk --no-cache add \ + php7 \ + php7-dom \ + php7-json \ + php7-mbstring \ + php7-pcntl \ + php7-sqlite3 \ + php7-tokenizer \ + tini + +# Builder +# ========== +FROM base AS builder + +ARG AST_VERSION +ARG PHAN_RELEASE + +# install build dependencies +RUN apk --no-cache add git build-base autoconf curl php7-dev php7-openssl php7-phar + +COPY --from=composer:1.7 /usr/bin/composer /usr/local/bin/composer + +# install php-ast +RUN set -xe; \ + \ + mkdir -p /src; \ + cd /src; \ + \ + git clone -b "v${AST_VERSION}" --single-branch --depth 1 https://github.com/nikic/php-ast.git; \ + \ + cd php-ast; \ + phpize7; \ + ./configure --with-php-config=php-config7; \ + make install; \ + echo "extension=ast.so" >> /etc/php7/php.ini + +# install phan +RUN set -xe; \ + \ + mkdir -p /src; \ + cd /src; \ + \ + if [[ "$PHAN_RELEASE" == "edge" ]]; then \ + git clone --single-branch --depth 1 https://github.com/phan/phan.git; \ + else \ + git clone -b $PHAN_RELEASE --single-branch --depth 1 https://github.com/phan/phan.git; \ + fi; \ + \ + cd phan; \ + /usr/local/bin/composer --prefer-dist --no-dev --no-interaction install; \ + rm -rf .git + +# Runtime +# ========== +FROM base AS runtime + +COPY --from=builder /src/phan /opt/phan +COPY --from=builder /usr/lib/php7/modules/ast.so /usr/lib/php7/modules/ast.so + +RUN echo "extension=ast.so" >> /etc/php7/php.ini + +COPY ./docker-entrypoint.sh / + +VOLUME /mnt/src + ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"] diff --git a/builder/scripts/docker-entrypoint.sh b/templates/versions/docker-entrypoint.sh similarity index 100% rename from builder/scripts/docker-entrypoint.sh rename to templates/versions/docker-entrypoint.sh diff --git a/templates/versions/options b/templates/versions/options index 7a52106..0032f72 100644 --- a/templates/versions/options +++ b/templates/versions/options @@ -1,5 +1,5 @@ export RELEASE="{{.VERSION}}" export MIRROR="http://mirror.sfo12.us.leaseweb.net/alpine" export AST="{{.AST}}" -export BUILD_OPTIONS=(-s -r $RELEASE -m $MIRROR -a $AST) +export BUILD_OPTIONS=(--build-arg APK_MIRROR=$MIRROR --build-arg AST_VERSION=$AST --build-arg PHAN_RELEASE=$RELEASE) export TAGS=(cloudflare/phan:{{.VERSION}}) diff --git a/test/test_cloudflare_phan-1.0.0.bats b/test/test_cloudflare_phan-1.0.0.bats new file mode 100644 index 0000000..a3ba132 --- /dev/null +++ b/test/test_cloudflare_phan-1.0.0.bats @@ -0,0 +1,36 @@ +setup() { + VERSION=1.0.0 + docker history "cloudflare/phan:${VERSION}" >/dev/null 2>&1 +} + +@test "pass arguments to phan" { + run docker run -v $PWD/test/fixtures/pass:/mnt/src "cloudflare/phan:${VERSION}" -h + [ $status -eq 0 ] + [ "${lines[0]}" = "Usage: /opt/phan/phan [options] [files...]" ] +} + +@test "outputs zero lines if source has no issues" { + run docker run -v $PWD/test/fixtures/pass:/mnt/src "cloudflare/phan:${VERSION}" \ + -l . + [ $status -eq 0 ] + [ ${#lines[@]} -eq 0 ] +} + +@test "outputs lines if source has issues" { + run docker run -v $PWD/test/fixtures/fail:/mnt/src "cloudflare/phan:${VERSION}" \ + -l . + + # even if there's failures, phan reports 1 + [ $status -eq 1 ] + + [ ${#lines[@]} -eq 2 ] + [ "${lines[0]}" = "undefined_class.php:3 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Stub" ] + [ "${lines[1]}" = "undefined_class.php:4 PhanUndeclaredClassConstant Reference to constant TYPE_STRING from undeclared class \Stub" ] +} + +@test "checkstyle output format is available" { + run docker run -v $PWD/test/fixtures/pass:/mnt/src "cloudflare/phan:${VERSION}" \ + --output-mode checkstyle -l . + [ $status -eq 0 ] + [ ${#lines[@]} -eq 2 ] +} diff --git a/test/test_cloudflare_phan-edge.bats b/test/test_cloudflare_phan-edge.bats index 6d98751..2908d1c 100644 --- a/test/test_cloudflare_phan-edge.bats +++ b/test/test_cloudflare_phan-edge.bats @@ -25,8 +25,8 @@ setup() { [ $status -eq 1 ] [ ${#lines[@]} -eq 2 ] - [ "${lines[0]}" = "./undefined_class.php:3 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Stub" ] - [ "${lines[1]}" = "./undefined_class.php:4 PhanUndeclaredClassConstant Reference to constant TYPE_STRING from undeclared class \Stub" ] + [ "${lines[0]}" = "undefined_class.php:3 PhanUndeclaredClassMethod Call to method __construct from undeclared class \Stub" ] + [ "${lines[1]}" = "undefined_class.php:4 PhanUndeclaredClassConstant Reference to constant TYPE_STRING from undeclared class \Stub" ] } @test "checkstyle output format is available" { diff --git a/versions/1.0.0/Dockerfile b/versions/1.0.0/Dockerfile new file mode 100644 index 0000000..22606df --- /dev/null +++ b/versions/1.0.0/Dockerfile @@ -0,0 +1,80 @@ +ARG ALPINE_VERSION=3.8 +ARG APK_MIRROR="http://nl.alpinelinux.org/alpine" +ARG AST_VERSION=0.1.5 +ARG PHAN_RELEASE="edge" + +# Baseline +# ========== +FROM alpine:$ALPINE_VERSION AS base + +# configure apk mirror +RUN echo "$APK_MIRROR/edge/main" >> "/etc/apk/repositories" \ + && echo "$APK_MIRROR/edge/community" >> "/etc/apk/repositories" + +# install runtime dependencies +RUN apk --no-cache add \ + php7 \ + php7-dom \ + php7-json \ + php7-mbstring \ + php7-pcntl \ + php7-sqlite3 \ + php7-tokenizer \ + tini + +# Builder +# ========== +FROM base AS builder + +ARG AST_VERSION +ARG PHAN_RELEASE + +# install build dependencies +RUN apk --no-cache add git build-base autoconf curl php7-dev php7-openssl php7-phar + +COPY --from=composer:1.7 /usr/bin/composer /usr/local/bin/composer + +# install php-ast +RUN set -xe; \ + \ + mkdir -p /src; \ + cd /src; \ + \ + git clone -b "v${AST_VERSION}" --single-branch --depth 1 https://github.com/nikic/php-ast.git; \ + \ + cd php-ast; \ + phpize7; \ + ./configure --with-php-config=php-config7; \ + make install; \ + echo "extension=ast.so" >> /etc/php7/php.ini + +# install phan +RUN set -xe; \ + \ + mkdir -p /src; \ + cd /src; \ + \ + if [[ "$PHAN_RELEASE" == "edge" ]]; then \ + git clone --single-branch --depth 1 https://github.com/phan/phan.git; \ + else \ + git clone -b $PHAN_RELEASE --single-branch --depth 1 https://github.com/phan/phan.git; \ + fi; \ + \ + cd phan; \ + /usr/local/bin/composer --prefer-dist --no-dev --no-interaction install; \ + rm -rf .git + +# Runtime +# ========== +FROM base AS runtime + +COPY --from=builder /src/phan /opt/phan +COPY --from=builder /usr/lib/php7/modules/ast.so /usr/lib/php7/modules/ast.so + +RUN echo "extension=ast.so" >> /etc/php7/php.ini + +COPY ./docker-entrypoint.sh / + +VOLUME /mnt/src + +ENTRYPOINT ["/sbin/tini", "-g", "--", "/docker-entrypoint.sh"] diff --git a/versions/1.0.0/docker-entrypoint.sh b/versions/1.0.0/docker-entrypoint.sh new file mode 100755 index 0000000..2c89c64 --- /dev/null +++ b/versions/1.0.0/docker-entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/sh +cd /mnt/src +exec php7 /opt/phan/phan "$@" diff --git a/versions/1.0.0/options b/versions/1.0.0/options new file mode 100644 index 0000000..b8310bf --- /dev/null +++ b/versions/1.0.0/options @@ -0,0 +1,5 @@ +export RELEASE="1.0.0" +export MIRROR="http://mirror.sfo12.us.leaseweb.net/alpine" +export AST="0.1.7" +export BUILD_OPTIONS=(--build-arg APK_MIRROR=$MIRROR --build-arg AST_VERSION=$AST --build-arg PHAN_RELEASE=$RELEASE) +export TAGS=(cloudflare/phan:1.0.0)