From a03fc2a5421ebd6a89a66a4227a680ec7772bf11 Mon Sep 17 00:00:00 2001
From: Olivier Benz <olivier.benz@b-data.ch>
Date: Tue, 23 Feb 2021 11:55:38 +0100
Subject: [PATCH] Freeze GHC version 8.8.4

---
 .gitlab-ci.yml    | 145 ++++++++++++++++++++++++++++++++++++++++++++++
 8.8.4.Dockerfile  | 124 +++++++++++++++++++++++++++++++++++++++
 Main.hs           |   4 ++
 latest.Dockerfile | 124 +++++++++++++++++++++++++++++++++++++++
 4 files changed, 397 insertions(+)
 create mode 100644 .gitlab-ci.yml
 create mode 100644 8.8.4.Dockerfile
 create mode 100644 Main.hs
 create mode 100644 latest.Dockerfile

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..1067529
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,145 @@
+.before-script-build: &before-script-build
+  - |
+    if [[ ! -z "$CI_BUILD_PLATFORMS" ]]; then
+      export OS_ARCH=`echo $CI_BUILD_PLATFORMS | tr ' ' '\n' | \
+      sed 's|\/||2' | sed 's|\/|-|' | tr '\n' ' '`
+    fi
+  - |
+    export CI_APP_REPO=${CI_APP_REPO:-$CI_REGISTRY_IMAGE}
+    if [[ $CI_COMMIT_BRANCH == "master" ]]; then
+      export CI_APP_TAG=${CI_APP_TAG:-latest}
+    elif [[ $CI_COMMIT_BRANCH == "freeze-version" ]]; then
+      export CI_APP_TAG=${CI_APP_TAG:-8.8.4}
+    else
+      export CI_APP_TAG=${CI_APP_TAG:-$CI_COMMIT_SHA}
+    fi
+  - >
+    echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER
+    --password-stdin $CI_REGISTRY
+  - |
+    export VERSION_MAJ_MIN_PAT=`sed -n \
+    "s|.*GHC_VERSION_BUILD:-\([0-9]\.[0-9]\.[0-9]\).*|\1|p" latest.Dockerfile \
+    | head -1`
+    export VERSION_MAJ_MIN=`echo "${VERSION_MAJ_MIN_PAT:0:3}"`
+    export VERSION_MAJ=`echo "${VERSION_MAJ_MIN_PAT:0:1}"`
+
+.build:
+  image: registry.gitlab.b-data.ch/docker/docker-buildx:latest
+  stage: build
+  services:
+    - docker:dind
+  variables:
+    DOCKER_DRIVER: overlay2
+    DOCKER_TLS_CERTDIR: "/certs"
+  before_script:
+    - *before-script-build
+
+build:latest-linux-amd64:
+  extends: .build
+  tags:
+    - arch:amd64
+    - os:linux
+  script:
+    - >
+      docker build -t $CI_APP_REPO:$CI_APP_TAG-linux-amd64
+      -t $CI_APP_REPO:$VERSION_MAJ_MIN_PAT-linux-amd64
+      -t $CI_APP_REPO:$VERSION_MAJ_MIN-linux-amd64
+      -t $CI_APP_REPO:$VERSION_MAJ-linux-amd64
+      -f $CI_APP_TAG.Dockerfile .
+    - docker push -a $CI_APP_REPO
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master" && $CI_BUILD_PLATFORMS =~ /(linux\/amd64)/
+      changes:
+        - latest.Dockerfile
+
+build:latest-linux-arm64v8:
+  extends: .build
+  tags:
+    - arch:arm64/v8
+    - os:linux
+  script:
+    - >
+      docker build -t $CI_APP_REPO:$CI_APP_TAG-linux-arm64v8
+      -t $CI_APP_REPO:$VERSION_MAJ_MIN_PAT-linux-arm64v8
+      -t $CI_APP_REPO:$VERSION_MAJ_MIN-linux-arm64v8
+      -t $CI_APP_REPO:$VERSION_MAJ-linux-arm64v8
+      -f $CI_APP_TAG.Dockerfile .
+    - docker push -a $CI_APP_REPO
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master" && $CI_BUILD_PLATFORMS =~ /(linux\/arm64\/v8)/
+      changes:
+        - latest.Dockerfile
+
+build:version-linux-amd64:
+  extends: .build
+  tags:
+    - arch:amd64
+    - os:linux
+  script:
+    - >
+      docker build -t $CI_APP_REPO:$CI_APP_TAG-linux-amd64
+      -f $CI_APP_TAG.Dockerfile .
+    - docker push -a $CI_APP_REPO
+  rules:
+    - if: $CI_COMMIT_BRANCH == "freeze-version" && $CI_BUILD_PLATFORMS =~ /(linux\/amd64)/
+      changes:
+        - 8.8.4.Dockerfile
+
+build:version-linux-arm64v8:
+  extends: .build
+  tags:
+    - arch:arm64/v8
+    - os:linux
+  script:
+    - >
+      docker build -t $CI_APP_REPO:$CI_APP_TAG-linux-arm64v8
+      -f $CI_APP_TAG.Dockerfile .
+    - docker push -a $CI_APP_REPO
+  rules:
+    - if: $CI_COMMIT_BRANCH == "freeze-version" && $CI_BUILD_PLATFORMS =~ /(linux\/arm64\/v8)/
+      changes:
+        - 8.8.4.Dockerfile
+
+build-manifest:latest-linux-multiarch:
+  extends: .build
+  stage: deploy
+  script:
+    - |
+      for i in $OS_ARCH; do
+        export CI_MANIFEST_LIST="$CI_MANIFEST_LIST $CI_APP_REPO:$CI_APP_TAG-$i"
+      done
+    - >    
+      docker manifest create $CI_APP_REPO:$CI_APP_TAG $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$CI_APP_TAG
+
+      docker manifest create $CI_APP_REPO:$VERSION_MAJ_MIN_PAT $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$VERSION_MAJ_MIN_PAT
+
+      docker manifest create $CI_APP_REPO:$VERSION_MAJ_MIN $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$VERSION_MAJ_MIN
+
+      docker manifest create $CI_APP_REPO:$VERSION_MAJ $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$VERSION_MAJ
+  rules:
+    - if: $CI_COMMIT_BRANCH == "master"
+      changes:
+        - latest.Dockerfile
+
+build-manifest:version-linux-multiarch:
+  extends: .build
+  stage: deploy
+  script:
+    - |
+      for i in $OS_ARCH; do
+        export CI_MANIFEST_LIST="$CI_MANIFEST_LIST $CI_APP_REPO:$CI_APP_TAG-$i"
+      done
+    - >    
+      docker manifest create $CI_APP_REPO:$CI_APP_TAG $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$CI_APP_TAG
+
+      docker manifest create $CI_APP_REPO:$VERSION_MAJ_MIN $CI_MANIFEST_LIST
+      && docker manifest push $CI_APP_REPO:$VERSION_MAJ_MIN
+  rules:
+    - if: $CI_COMMIT_BRANCH == "freeze-version"
+      changes:
+        - 8.8.4.Dockerfile
diff --git a/8.8.4.Dockerfile b/8.8.4.Dockerfile
new file mode 100644
index 0000000..768d8d4
--- /dev/null
+++ b/8.8.4.Dockerfile
@@ -0,0 +1,124 @@
+ARG GHC_VERSION_BUILD
+ARG CABAL_VERSION_BUILD
+
+FROM registry.gitlab.b-data.ch/ghc/ghc4pandoc:bootstrap as bootstrap
+
+ENV GHC_VERSION=${GHC_VERSION_BUILD:-8.8.4}
+ENV CABAL_VERSION=${CABAL_VERSION_BUILD:-3.2.0.0}
+
+RUN apk add --update --no-cache \
+    autoconf \
+    automake \
+    binutils-gold \
+    build-base \
+    coreutils \
+    cpio \
+    curl \
+    gnupg \
+    linux-headers \
+    libffi-dev \
+    ncurses-dev \
+    perl \
+    python3 \
+    xz \
+    zlib-dev
+
+RUN cd /tmp \
+  && curl -sSLO https://downloads.haskell.org/~ghc/$GHC_VERSION/ghc-$GHC_VERSION-src.tar.xz \
+  && curl -sSLO https://downloads.haskell.org/~ghc/$GHC_VERSION/ghc-$GHC_VERSION-src.tar.xz.sig \
+  && gpg --keyserver hkps://keyserver.ubuntu.com:443 \
+    --receive-keys FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD \
+  && gpg --verify ghc-$GHC_VERSION-src.tar.xz.sig ghc-$GHC_VERSION-src.tar.xz \
+  && tar xf ghc-$GHC_VERSION-src.tar.xz \
+  && cd ghc-$GHC_VERSION \
+  # Set llvm version to 10
+  && sed -i -e 's/LlvmVersion=7/LlvmVersion=10/g' configure.ac \
+  && cp mk/build.mk.sample mk/build.mk \
+  && echo 'BuildFlavour=perf-llvm' >> mk/build.mk \
+  && echo 'BeConservative=YES' >> mk/build.mk \
+  && echo 'HADDOCK_DOCS=NO' >> mk/build.mk \
+  && echo 'HSCOLOUR_SRCS=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_HTML=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_PS=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_PDF=NO' >> mk/build.mk \
+  && autoreconf \
+  && ./configure --disable-ld-override \
+  # Switch llvm-targets from unknown-linux-gnueabihf->alpine-linux
+  # so we can match the llvm vendor string alpine uses
+  && sed -i -e 's/unknown-linux-gnueabihf/alpine-linux/g' llvm-targets \
+  && sed -i -e 's/unknown-linux-gnueabi/alpine-linux/g' llvm-targets \
+  && sed -i -e 's/unknown-linux-gnu/alpine-linux/g' llvm-targets \
+  # See https://unix.stackexchange.com/questions/519092/what-is-the-logic-of-using-nproc-1-in-make-command
+  && make -j$((`nproc`+1)) \
+  && make binary-dist \
+  && cabal update \
+  # See https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/libraries/version-history
+  && cabal install cabal-install-$CABAL_VERSION
+
+FROM alpine:3.12 as builder
+
+LABEL org.label-schema.license="MIT" \
+      org.label-schema.vcs-url="https://gitlab.b-data.ch/ghc/ghc4pandoc" \
+      maintainer="Olivier Benz <olivier.benz@b-data.ch>"
+
+ENV GHC_VERSION=${GHC_VERSION_BUILD:-8.8.4}
+ENV CABAL_VERSION=${CABAL_VERSION_BUILD:-3.2.0.0}
+
+RUN apk add --update --no-cache \
+    bash \
+    build-base \
+    bzip2 \
+    bzip2-dev \
+    bzip2-static \
+    curl \
+    curl-static \
+    dpkg \
+    fakeroot \
+    git \
+    gmp-dev \
+    libcurl \
+    libffi \
+    libffi-dev \
+    llvm10 \
+    ncurses-dev \
+    ncurses-static \
+    openssl-dev \
+    openssl-libs-static \
+    pcre \
+    pcre-dev \
+    pcre2 \
+    pcre2-dev \
+    perl \
+    wget \
+    xz \
+    xz-dev \
+    zlib \
+    zlib-dev \
+    zlib-static
+
+COPY --from=bootstrap /tmp/ghc-$GHC_VERSION/ghc-$GHC_VERSION-*-alpine-linux.tar.xz /tmp/
+COPY --from=bootstrap /root/.cabal/bin/cabal /usr/bin/cabal
+
+RUN cd /tmp \
+  && tar -xJf ghc-$GHC_VERSION-*-alpine-linux.tar.xz \
+  && cd ghc-$GHC_VERSION \
+  && ./configure --prefix=/usr \
+  && make install \
+  && cd / \
+  && rm -rf /tmp/*
+
+FROM builder as tester
+
+COPY Main.hs Main.hs
+
+RUN ghc -static -optl-pthread -optl-static Main.hs \
+  && file Main \
+  && ./Main \
+  # Test cabal workflow
+  && mkdir cabal-test \
+  && cd cabal-test \
+  && cabal update \
+  && cabal init -n --is-executable -p tester -l BSD3 \
+  && cabal run
+
+FROM builder as final
diff --git a/Main.hs b/Main.hs
new file mode 100644
index 0000000..8e366f2
--- /dev/null
+++ b/Main.hs
@@ -0,0 +1,4 @@
+module Main (main) where
+
+main :: IO ()
+main = putStrLn "Hello, World!"
diff --git a/latest.Dockerfile b/latest.Dockerfile
new file mode 100644
index 0000000..768d8d4
--- /dev/null
+++ b/latest.Dockerfile
@@ -0,0 +1,124 @@
+ARG GHC_VERSION_BUILD
+ARG CABAL_VERSION_BUILD
+
+FROM registry.gitlab.b-data.ch/ghc/ghc4pandoc:bootstrap as bootstrap
+
+ENV GHC_VERSION=${GHC_VERSION_BUILD:-8.8.4}
+ENV CABAL_VERSION=${CABAL_VERSION_BUILD:-3.2.0.0}
+
+RUN apk add --update --no-cache \
+    autoconf \
+    automake \
+    binutils-gold \
+    build-base \
+    coreutils \
+    cpio \
+    curl \
+    gnupg \
+    linux-headers \
+    libffi-dev \
+    ncurses-dev \
+    perl \
+    python3 \
+    xz \
+    zlib-dev
+
+RUN cd /tmp \
+  && curl -sSLO https://downloads.haskell.org/~ghc/$GHC_VERSION/ghc-$GHC_VERSION-src.tar.xz \
+  && curl -sSLO https://downloads.haskell.org/~ghc/$GHC_VERSION/ghc-$GHC_VERSION-src.tar.xz.sig \
+  && gpg --keyserver hkps://keyserver.ubuntu.com:443 \
+    --receive-keys FFEB7CE81E16A36B3E2DED6F2DE04D4E97DB64AD \
+  && gpg --verify ghc-$GHC_VERSION-src.tar.xz.sig ghc-$GHC_VERSION-src.tar.xz \
+  && tar xf ghc-$GHC_VERSION-src.tar.xz \
+  && cd ghc-$GHC_VERSION \
+  # Set llvm version to 10
+  && sed -i -e 's/LlvmVersion=7/LlvmVersion=10/g' configure.ac \
+  && cp mk/build.mk.sample mk/build.mk \
+  && echo 'BuildFlavour=perf-llvm' >> mk/build.mk \
+  && echo 'BeConservative=YES' >> mk/build.mk \
+  && echo 'HADDOCK_DOCS=NO' >> mk/build.mk \
+  && echo 'HSCOLOUR_SRCS=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_HTML=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_PS=NO' >> mk/build.mk \
+  && echo 'BUILD_SPHINX_PDF=NO' >> mk/build.mk \
+  && autoreconf \
+  && ./configure --disable-ld-override \
+  # Switch llvm-targets from unknown-linux-gnueabihf->alpine-linux
+  # so we can match the llvm vendor string alpine uses
+  && sed -i -e 's/unknown-linux-gnueabihf/alpine-linux/g' llvm-targets \
+  && sed -i -e 's/unknown-linux-gnueabi/alpine-linux/g' llvm-targets \
+  && sed -i -e 's/unknown-linux-gnu/alpine-linux/g' llvm-targets \
+  # See https://unix.stackexchange.com/questions/519092/what-is-the-logic-of-using-nproc-1-in-make-command
+  && make -j$((`nproc`+1)) \
+  && make binary-dist \
+  && cabal update \
+  # See https://gitlab.haskell.org/ghc/ghc/-/wikis/commentary/libraries/version-history
+  && cabal install cabal-install-$CABAL_VERSION
+
+FROM alpine:3.12 as builder
+
+LABEL org.label-schema.license="MIT" \
+      org.label-schema.vcs-url="https://gitlab.b-data.ch/ghc/ghc4pandoc" \
+      maintainer="Olivier Benz <olivier.benz@b-data.ch>"
+
+ENV GHC_VERSION=${GHC_VERSION_BUILD:-8.8.4}
+ENV CABAL_VERSION=${CABAL_VERSION_BUILD:-3.2.0.0}
+
+RUN apk add --update --no-cache \
+    bash \
+    build-base \
+    bzip2 \
+    bzip2-dev \
+    bzip2-static \
+    curl \
+    curl-static \
+    dpkg \
+    fakeroot \
+    git \
+    gmp-dev \
+    libcurl \
+    libffi \
+    libffi-dev \
+    llvm10 \
+    ncurses-dev \
+    ncurses-static \
+    openssl-dev \
+    openssl-libs-static \
+    pcre \
+    pcre-dev \
+    pcre2 \
+    pcre2-dev \
+    perl \
+    wget \
+    xz \
+    xz-dev \
+    zlib \
+    zlib-dev \
+    zlib-static
+
+COPY --from=bootstrap /tmp/ghc-$GHC_VERSION/ghc-$GHC_VERSION-*-alpine-linux.tar.xz /tmp/
+COPY --from=bootstrap /root/.cabal/bin/cabal /usr/bin/cabal
+
+RUN cd /tmp \
+  && tar -xJf ghc-$GHC_VERSION-*-alpine-linux.tar.xz \
+  && cd ghc-$GHC_VERSION \
+  && ./configure --prefix=/usr \
+  && make install \
+  && cd / \
+  && rm -rf /tmp/*
+
+FROM builder as tester
+
+COPY Main.hs Main.hs
+
+RUN ghc -static -optl-pthread -optl-static Main.hs \
+  && file Main \
+  && ./Main \
+  # Test cabal workflow
+  && mkdir cabal-test \
+  && cd cabal-test \
+  && cabal update \
+  && cabal init -n --is-executable -p tester -l BSD3 \
+  && cabal run
+
+FROM builder as final
-- 
GitLab