diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..42e7609 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,96 @@ +version: 2.1 +orbs: + docker: circleci/docker@1.4.0 +jobs: + perl: + executor: docker/docker + steps: + - setup_remote_docker + - checkout + - run: + command: | + echo Log in as "$DOCKER_LOGIN" + echo "$DOCKER_PASSWORD" | docker login --username "$DOCKER_LOGIN" --password-stdin + docker build -t deriv/perl . + name: Build deriv/perl + dzil: + executor: docker/docker + steps: + - setup_remote_docker + - checkout + - run: + command: | + echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_LOGIN" --password-stdin + cd dzil && docker build -t deriv/dzil . + name: Build deriv/dzil +workflows: + version: 2 + build-workflow: + jobs: + - perl: + context: perl + - dzil: + context: perl + requires: + - perl + - docker/hadolint: + dockerfiles: Dockerfile:dzil/Dockerfile + # Don't pin apt versions, we'll never remember to update them + ignore-rules: DL3008,SC2046,DL3003,DL4006,DL3006 + merged: + jobs: + - docker/publish: + deploy: true + image: deriv/perl + filters: + branches: + only: /^master$/ + - docker/publish: + deploy: true + image: deriv/dzil + path: dzil + filters: + branches: + only: /^master$/ + - docker/hadolint: + dockerfiles: Dockerfile:dzil/Dockerfile + # Don't pin apt versions, we'll never remember to update them + ignore-rules: DL3008,SC2046,DL3003,DL4006,DL3006 + filters: + branches: + only: /^master$/ + tagged: + jobs: + - docker/publish: + deploy: true + image: deriv/perl + filters: + branches: + only: /^master$/ + - docker/publish: + deploy: true + image: deriv/dzil + path: dzil + filters: + branches: + only: /^master$/ + daily: + jobs: + - docker/publish: + deploy: false + image: deriv/perl + - docker/publish: + deploy: false + image: deriv/dzil + path: dzil + - docker/hadolint: + dockerfiles: Dockerfile:dzil/Dockerfile + # Don't pin apt versions, we'll never remember to update them + ignore-rules: DL3008,SC2046,DL3003,DL4006,DL3006 + triggers: + - schedule: + cron: 05 19 * * * + filters: + branches: + only: + - master diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 595669f..b3d4d78 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,4 +1,4 @@ -name: Build image +name: Build images on: push: @@ -13,12 +13,15 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@master - - name: Build base perl image + - name: Build images run: | docker version [ -n $DEBIAN_PROXY ] && docker_build_opts="--build-arg=DEBIAN_PROXY=${DEBIAN_PROXY}" docker build "$docker_build_opts" -t deriv/perl . + cd dzil && docker build "$docker_build_opts" -t deriv/dzil . - name: Inspect image creation and tag time run: | docker image inspect --format \'{{.Created}}\' deriv/perl docker image inspect --format \'{{.Metadata.LastTagTime}}\' deriv/perl + docker image inspect --format \'{{.Created}}\' deriv/dzil + docker image inspect --format \'{{.Metadata.LastTagTime}}\' deriv/dzil diff --git a/Dockerfile b/Dockerfile index 6a39e8c..1276680 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,60 +12,51 @@ ENV CPANM_SHA256=9b60767fe40752ef7a9d3f13f19060a63389a5c23acc3e9827e19b75500f81f # Use an apt-cacher-ng or similar proxy when available during builds ARG DEBIAN_PROXY +ARG HTTP_PROXY WORKDIR /usr/src/perl RUN [ -n "$DEBIAN_PROXY" ] \ && (echo "Acquire::http::Proxy \"http://$DEBIAN_PROXY\";" > /etc/apt/apt.conf.d/30proxy) \ - && (echo "Acquire::http::Proxy::ppa.launchpad.net DIRECT;" >> /etc/apt/apt.conf.d/30proxy) \ || echo "No local Debian proxy configured" \ && apt-get update \ && apt-get dist-upgrade -y -q --no-install-recommends \ && apt-get install -y -q --no-install-recommends \ - git openssh-client curl socat ca-certificates gcc make libc6-dev libssl-dev zlib1g-dev xz-utils dumb-init \ - && curl -SL https://www.cpan.org/src/5.0/perl-${PERL_VERSION}.tar.xz -o perl-${PERL_VERSION}.tar.xz \ + git openssh-client curl socat ca-certificates gcc make libc6-dev libssl-dev zlib1g-dev xz-utils dumb-init patch \ + && curl -SL https://www.cpan.org/src/5.0/"perl-${PERL_VERSION}".tar.xz -o "perl-${PERL_VERSION}".tar.xz \ && echo "${PERL_SHA256} *perl-${PERL_VERSION}.tar.xz" | sha256sum -c - \ - && tar --strip-components=1 -xaf perl-${PERL_VERSION}.tar.xz -C /usr/src/perl \ - && rm perl-${PERL_VERSION}.tar.xz \ - && ./Configure -Duse64bitall -Duseshrplib -Dprefix=/opt/perl-${PERL_VERSION} -Dman1dir=none -Dman3dir=none -des \ + && tar --strip-components=1 -xaf "perl-${PERL_VERSION}".tar.xz -C /usr/src/perl \ + && rm "perl-${PERL_VERSION}".tar.xz \ + && ./Configure -Duse64bitall -Duseshrplib -Dprefix=/opt/"perl-${PERL_VERSION}" -Dman1dir=none -Dman3dir=none -des \ && make -j$(nproc) \ && make install \ && cd /usr/src \ && curl -LO https://www.cpan.org/authors/id/M/MI/MIYAGAWA/App-cpanminus-${CPANM_VERSION}.tar.gz \ && echo "${CPANM_SHA256} *App-cpanminus-${CPANM_VERSION}.tar.gz" | sha256sum -c - \ - && tar -xzf App-cpanminus-${CPANM_VERSION}.tar.gz \ - && rm App-cpanminus-${CPANM_VERSION}.tar.gz \ - && cd App-cpanminus-${CPANM_VERSION} && /opt/perl-${PERL_VERSION}/bin/perl bin/cpanm . \ - && rm -rf /var/lib/apt/lists/* /var/cache/apt/* \ - && rm -fr ./cpanm /root/.cpanm /usr/src/perl /usr/src/App-cpanminus-${CPANM_VERSION}* /tmp/* \ -# Locale support is probably quite useful in some cases, but -# let's let individual builds decide that via aptfile config -# && echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen \ -# && locale-gen \ + && tar -xzf "App-cpanminus-${CPANM_VERSION}".tar.gz \ + && rm "App-cpanminus-${CPANM_VERSION}".tar.gz \ + && cd "App-cpanminus-${CPANM_VERSION}" && /opt/"perl-${PERL_VERSION}"/bin/perl bin/cpanm . \ + && rm -rf /var/lib/apt/lists/* /var/cache/apt/* /etc/apt/apt.conf.d/30proxy \ + && rm -fr ./cpanm /root/.cpanm /usr/src/perl /usr/src/"App-cpanminus-${CPANM_VERSION}"* /tmp/* \ && mkdir -p /etc/ssh/ \ && ssh-keyscan github.com >> /etc/ssh/ssh_known_hosts \ && mkdir -p /app WORKDIR /app/ +COPY prepare-apt-cpan.sh /usr/local/bin/ ENV PATH="/opt/perl-${PERL_VERSION}/bin:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:/usr/local/sbin" -ONBUILD ADD cpanfile aptfile /app/ +ONBUILD ARG HTTP_PROXY +ONBUILD WORKDIR /app/ +ONBUILD COPY cpanfile aptfile /app/ # Install everything in the aptfile first, as system deps, then # go through the CPAN deps. Once those are all done, remove anything # that we would have pulled in as a build dep (compilers, for example) # unless they happened to be in the aptfile. -ONBUILD RUN if [ -s /app/aptfile ]; then \ - apt-get -y -q update \ - && apt-get -y -q --no-install-recommends install $(cat /app/aptfile); \ - fi \ - && cpanm --notest --quiet --installdeps --with-recommends . \ - && apt-get purge -y -q $(perl -le'@seen{split " ", "" . do { local ($/, @ARGV) = (undef, "/app/aptfile"); <> }} = () if -r "aptfile"; print for grep { !exists $seen{$_} } qw(make gcc git openssh-client libc6-dev libssl-dev zlib1g-dev)') \ - && apt-get -y --purge autoremove \ - && rm -rf /var/lib/apt/lists/* /var/cache/apt/* /root/.cpanm /tmp/* - -ONBUILD ADD . /app/ +ONBUILD RUN prepare-apt-cpan.sh +ONBUILD COPY . /app/ ENTRYPOINT [ "/usr/bin/dumb-init", "--" ] diff --git a/dzil/Dockerfile b/dzil/Dockerfile new file mode 100644 index 0000000..483b457 --- /dev/null +++ b/dzil/Dockerfile @@ -0,0 +1,8 @@ +ARG HTTP_PROXY +FROM deriv/perl +COPY pod-inherit.patch . +RUN patch -p0 $(perldoc -lm Pod::Inherit) < pod-inherit.patch +ONBUILD COPY cpanfile aptfile dist.ini /app/ +ONBUILD RUN prepare-apt-cpan.sh \ + && dzil authordeps | cpanm -n +ONBUILD COPY . /app/ diff --git a/dzil/aptfile b/dzil/aptfile new file mode 100644 index 0000000..1b7ae82 --- /dev/null +++ b/dzil/aptfile @@ -0,0 +1,8 @@ +libncurses-dev +libreadline-dev +git +gcc +make +libc6-dev +openssh-client +patch diff --git a/dzil/cpanfile b/dzil/cpanfile new file mode 100644 index 0000000..f8f0d27 --- /dev/null +++ b/dzil/cpanfile @@ -0,0 +1 @@ +requires 'Dist::Zilla::PluginBundle::Author::DERIV'; diff --git a/dzil/pod-inherit.patch b/dzil/pod-inherit.patch new file mode 100644 index 0000000..808081a --- /dev/null +++ b/dzil/pod-inherit.patch @@ -0,0 +1,22 @@ +--- a/Pod/Inherit.pm 2020-04-03 21:58:36.470197738 +0800 ++++ b/Pod/Inherit.pm 2014-06-13 10:45:18.000000000 +0800 +@@ -909,7 +909,7 @@ + unless (exists $INC{$class_as_filename}) { + # Still no source? Great... we'll have to pray that require will work... + print "Still no source found for $classname; forced to use 'require'\n" if ($DEBUG && !$src); +- my $did_it = $src ? do $src : Class::Load::load_optional_class($classname); ++ my $did_it = $src ? do "./$src" : Class::Load::load_optional_class($classname); + unless ($did_it) { + my $err = $@; + $err =~ s/ \(\@INC contains: .*\)//; +@@ -994,7 +994,10 @@ + $src = Path::Class::File->new($src)->as_foreign('Unix'); + + return <<__END_HEADER__; ++=encoding utf8 ++ + =for comment POD_DERIVED_INDEX_GENERATED ++ + The following documentation is automatically generated. Please do not edit + this file, but rather the original, inline with $classname + at $src diff --git a/prepare-apt-cpan.sh b/prepare-apt-cpan.sh new file mode 100755 index 0000000..2c3332d --- /dev/null +++ b/prepare-apt-cpan.sh @@ -0,0 +1,14 @@ +#!/bin/bash +# Prepare dependencies by installing anything found in `aptfile` +# then applying CPAN modules from `cpanfile`. + +set -e + +if [ -r /app/aptfile ]; then + apt-get -y -q update + apt-get -y -q --no-install-recommends install $(cat /app/aptfile) +fi +cpanm --notest --installdeps . +apt-get purge -y -q $(perl -le'@seen{split " ", "" . do { local ($/, @ARGV) = (undef, "/app/aptfile"); <> }} = () if -r "aptfile"; print for grep { !exists $seen{$_} } qw(make gcc git openssh-client libc6-dev libssl-dev zlib1g-dev patch)') +rm -rf /var/lib/apt/lists/* /var/cache/apt/* /root/.cpanm /tmp/* +