From 96751d6c3fbdfb5780d83165758d6842e10e021e Mon Sep 17 00:00:00 2001
From: Thom Nichols <95562+thom-nic@users.noreply.github.com>
Date: Tue, 31 Oct 2023 10:24:41 -0400
Subject: [PATCH] use --platform to consolidate dockerfiles

---
 .github/workflows/build-pack-publish.yml | 41 ++++++++++++++++------
 Dockerfile-arm => Dockerfile             | 21 ++++++++---
 Dockerfile-alpine                        |  3 +-
 Dockerfile-alpine-arm                    | 39 ---------------------
 Dockerfile-alpine-arm64                  | 39 ---------------------
 Dockerfile-arm64                         | 44 ------------------------
 Dockerfile-x64                           | 43 -----------------------
 build-all.sh                             | 38 ++++++++++----------
 8 files changed, 68 insertions(+), 200 deletions(-)
 rename Dockerfile-arm => Dockerfile (55%)
 delete mode 100755 Dockerfile-alpine-arm
 delete mode 100755 Dockerfile-alpine-arm64
 delete mode 100755 Dockerfile-arm64
 delete mode 100755 Dockerfile-x64

diff --git a/.github/workflows/build-pack-publish.yml b/.github/workflows/build-pack-publish.yml
index a5ef4a0..c7f9a3b 100644
--- a/.github/workflows/build-pack-publish.yml
+++ b/.github/workflows/build-pack-publish.yml
@@ -11,29 +11,50 @@ on:
 jobs:
 
   build:
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     strategy:
       matrix:
-        arch: [x64, arm, arm64, alpine, alpine-arm, alpine-arm64]
+        os: [linux]
+        arch: [amd64, arm64, arm]
     steps:
       - uses: actions/checkout@v2
       - uses: docker/setup-qemu-action@v1
         with:
           image: tonistiigi/binfmt:latest
-          platforms: arm,arm64  #all
-      - run: docker build . -f ./Dockerfile-${{ matrix.arch }}
-             --tag node-bcrypt-builder-${{ matrix.arch }}
-      - run: docker create --name node-bcryptjs-builder node-bcrypt-builder-${{ matrix.arch }}
+          platforms: arm,arm64
+
+      - run: >
+          docker build .
+          --tag node-bcrypt-builder
+          --platform ${{ matrix.os }}/${{ matrix.arch }}
+      - run: >
+          docker create
+          --name node-bcryptjs-builder
+          --platform ${{ matrix.os }}/${{ matrix.arch }}
+          node-bcrypt-builder
       - run: docker cp "node-bcryptjs-builder:/usr/local/opt/bcrypt-js/prebuilds" .
+
+      # build for Alpine:
+      - run: >
+          docker build -f Dockerfile-alpine .
+          --tag node-bcrypt-builder-alpine
+          --platform ${{ matrix.os }}/${{ matrix.arch }}
+      - run: >
+          docker create
+          --name node-bcryptjs-builder-alpine
+          --platform ${{ matrix.os }}/${{ matrix.arch }}
+          node-bcrypt-builder-alpine
+      - run: docker cp "node-bcryptjs-builder-alpine:/usr/local/opt/bcrypt-js/prebuilds" .
+
       - run: find prebuilds
       - uses: actions/upload-artifact@v2
         with:
-          name: prebuild-${{ matrix.arch }}
+          name: prebuild-${{ matrix.os }}-${{ matrix.arch }}
           path: ./prebuilds
 
   pack:
     needs: build
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-node@v2
@@ -60,7 +81,7 @@ jobs:
   publish-npm:
     needs: pack
     if: github.event_name == 'release'
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     steps:
       - uses: actions/checkout@v2
       - uses: actions/setup-node@v2
@@ -78,7 +99,7 @@ jobs:
   publish-gpr:
     needs: pack
     if: github.event_name == 'release'
-    runs-on: ubuntu-latest
+    runs-on: ubuntu-22.04
     permissions:
       contents: read
       packages: write
diff --git a/Dockerfile-arm b/Dockerfile
similarity index 55%
rename from Dockerfile-arm
rename to Dockerfile
index 3e13638..da3b22f 100755
--- a/Dockerfile-arm
+++ b/Dockerfile
@@ -1,11 +1,24 @@
 # Usage:
 #
-#   docker build -t bcryptjs-linux-arm-builder -f Dockerfile-arm .
-#   docker create --name donut bcryptjs-linux-arm-builder
+#   docker build -t bcryptjs-builder .
+#   CONTAINER=$(docker create bcryptjs-builder)
 #   # Then copy the artifact to your host:
-#   docker cp donut:/usr/local/opt/bcrypt-js/prebuilds .
+#   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
+#   docker rm "$CONTAINER"
+#
+# Use --platform to build cross-platform i.e. for ARM:
+#
+#   docker build -t bcryptjs-builder --platform "linux/arm64/v8" .
+#   CONTAINER=$docker create --platform "linux/arm64/v8" bcryptjs-builder)
+#   # this copies the prebuilds/linux-arm artifacts
+#   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
+#   docker rm "$CONTAINER"
+
 
-FROM arm32v7/node:16-bullseye
+ARG FROM_IMAGE=node:18-bullseye
+#ARG FROM_IMAGE=arm32v7/node:16-bullseye
+#ARG FROM_IMAGE=arm64v8/node:16-bullseye
+FROM ${FROM_IMAGE}
 
 ENV project bcrypt-js
 ENV DEBIAN_FRONTEND noninteractive
diff --git a/Dockerfile-alpine b/Dockerfile-alpine
index 8d700ae..7ee6206 100755
--- a/Dockerfile-alpine
+++ b/Dockerfile-alpine
@@ -6,7 +6,8 @@
 #   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
 #   docker rm "$CONTAINER"
 
-FROM node:16-alpine
+ARG FROM_IMAGE=node:18-alpine
+FROM ${FROM_IMAGE}
 
 ENV project bcrypt-js
 ENV DEBIAN_FRONTEND noninteractive
diff --git a/Dockerfile-alpine-arm b/Dockerfile-alpine-arm
deleted file mode 100755
index 8e1421e..0000000
--- a/Dockerfile-alpine-arm
+++ /dev/null
@@ -1,39 +0,0 @@
-# Usage:
-#
-#   docker build -t bcryptjs-alpine-arm-builder -f Dockerfile-arm .
-#   CONTAINER=$(docker create bcryptjs-alpine-arm-builder)
-#   # Then copy the artifact to your host:
-#   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
-#   docker rm "$CONTAINER"
-
-FROM arm32v7/node:16-alpine
-
-ENV project bcrypt-js
-ENV DEBIAN_FRONTEND noninteractive
-ENV LC_ALL en_US.UTF-8
-ENV LANG ${LC_ALL}
-
-RUN echo "#log: ${project}: Setup system" \
-  && set -x \
-  && apk add --update build-base python3 \
-  && npm i -g prebuildify@5 node-gyp@9 \
-  && sync
-
-ADD . /usr/local/opt/${project}
-WORKDIR /usr/local/opt/${project}
-
-RUN echo "#log: ${project}: Running build" \
-  && set -x \
-  && npm ci \
-  && npm run build
-
-ARG RUN_TESTS=true
-
-RUN if "${RUN_TESTS}"; then \
-    echo "#log ${project}: Running tests" \
-    && npm test; \
-  else \
-    echo "#log ${project}: Tests were skipped!"; \
-  fi
-
-CMD /bin/bash -l
diff --git a/Dockerfile-alpine-arm64 b/Dockerfile-alpine-arm64
deleted file mode 100755
index 0ea04fe..0000000
--- a/Dockerfile-alpine-arm64
+++ /dev/null
@@ -1,39 +0,0 @@
-# Usage:
-#
-#   docker build -t bcryptjs-alpine-arm-builder -f Dockerfile-arm .
-#   CONTAINER=$(docker create bcryptjs-alpine-arm-builder)
-#   # Then copy the artifact to your host:
-#   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
-#   docker rm "$CONTAINER"
-
-FROM arm64v8/node:16-alpine
-
-ENV project bcrypt-js
-ENV DEBIAN_FRONTEND noninteractive
-ENV LC_ALL en_US.UTF-8
-ENV LANG ${LC_ALL}
-
-RUN echo "#log: ${project}: Setup system" \
-  && set -x \
-  && apk add --update build-base python3 \
-  && npm i -g prebuildify@5 node-gyp@9 \
-  && sync
-
-ADD . /usr/local/opt/${project}
-WORKDIR /usr/local/opt/${project}
-
-RUN echo "#log: ${project}: Running build" \
-  && set -x \
-  && npm ci \
-  && npm run build
-
-ARG RUN_TESTS=true
-
-RUN if "${RUN_TESTS}"; then \
-    echo "#log ${project}: Running tests" \
-    && npm test; \
-  else \
-    echo "#log ${project}: Tests were skipped!"; \
-  fi
-
-CMD /bin/bash -l
diff --git a/Dockerfile-arm64 b/Dockerfile-arm64
deleted file mode 100755
index 8d356f1..0000000
--- a/Dockerfile-arm64
+++ /dev/null
@@ -1,44 +0,0 @@
-# Usage:
-#
-#   docker build -t bcryptjs-linux-arm64-builder -f Dockerfile-arm64 .
-#   docker create --name donut-arm64 bcryptjs-linux-arm64-builder
-#   # Then copy the artifact to your host:
-#   docker cp donut-arm64:/usr/local/opt/bcrypt-js/prebuilds .
-
-FROM arm64v8/node:16-bullseye
-
-ENV project bcrypt-js
-ENV DEBIAN_FRONTEND noninteractive
-ENV LC_ALL en_US.UTF-8
-ENV LANG ${LC_ALL}
-
-RUN echo "#log: ${project}: Setup system" \
-  && set -x \
-  && apt-get update -y \
-  && apt-get install -y \
-    build-essential \
-    python3 \
-  && apt-get clean \
-  && update-alternatives --install /usr/local/bin/python python /usr/bin/python3 20 \
-  && npm i -g prebuildify@5 node-gyp@9 \
-  && sync
-
-ADD . /usr/local/opt/${project}
-WORKDIR /usr/local/opt/${project}
-
-RUN echo "#log: ${project}: Running build" \
-  && set -x \
-  && npm ci \
-  && npm run build
-
-ARG RUN_TESTS=true
-
-RUN if "${RUN_TESTS}"; then \
-    echo "#log ${project}: Running tests" \
-    && npm test; \
-  else \
-    echo "#log ${project}: Tests were skipped!"; \
-  fi
-
-CMD /bin/bash -l
-
diff --git a/Dockerfile-x64 b/Dockerfile-x64
deleted file mode 100755
index e6fc7a3..0000000
--- a/Dockerfile-x64
+++ /dev/null
@@ -1,43 +0,0 @@
-# Usage:
-#
-#   docker build -t bcryptjs-linux-x64-builder .
-#   docker create --name donut bcryptjs-linux-x64-builder
-#   # Then copy the artifact to your host:
-#   docker cp donut:/usr/local/opt/bcrypt-js/prebuilds .
-
-FROM node:16-bullseye
-
-ENV project bcrypt-js
-ENV DEBIAN_FRONTEND noninteractive
-ENV LC_ALL en_US.UTF-8
-ENV LANG ${LC_ALL}
-
-RUN echo "#log: ${project}: Setup system" \
-  && set -x \
-  && apt-get update -y \
-  && apt-get install -y \
-    build-essential \
-    python3 \
-  && apt-get clean \
-  && update-alternatives --install /usr/local/bin/python python /usr/bin/python3 20 \
-  && npm i -g prebuildify@5 node-gyp@9 \
-  && sync
-
-ADD . /usr/local/opt/${project}
-WORKDIR /usr/local/opt/${project}
-
-RUN echo "#log: ${project}: Running build" \
-  && set -x \
-  && npm ci \
-  && npm run build
-
-ARG RUN_TESTS=true
-
-RUN if "${RUN_TESTS}"; then \
-    echo "#log ${project}: Running tests" \
-    && npm test; \
-  else \
-    echo "#log ${project}: Tests were skipped!"; \
-  fi
-
-CMD /bin/bash -l
diff --git a/build-all.sh b/build-all.sh
index fcd89ab..75bf498 100755
--- a/build-all.sh
+++ b/build-all.sh
@@ -5,35 +5,33 @@ RUN_TESTS=${RUN_TESTS:-true}
 
 if [ -n "$CLEAN" ]; then
   rm -rf build build-tmp*
+  rm -rf lib/binding
   rm -rf prebuilds
 fi
 
-npm i
-npm i -g prebuildify node-gyp
-npm run build
+npm i -g prebuildify@5 node-gyp@9
+npm ci
+#npm run build
 
-# build for linux/x64:
-if [ ! -d prebuilds/linux-x64 ]; then
-  docker build -t bcryptjs-linux-x64-builder -f Dockerfile-x64 --build-arg RUN_TESTS="$RUN_TESTS" .
-  CONTAINER=$(docker create bcryptjs-linux-x64-builder)
+for PLATFORM in linux/amd64 linux/arm64/v8 linux/arm/v7; do
+  echo -- build for $PLATFORM --
+  BUILDER_NAME="bcryptjs-${PLATFORM//\/-}-builder"
+  docker build -t "$BUILDER_NAME" \
+      --build-arg RUN_TESTS="$RUN_TESTS" \
+      --platform "$PLATFORM" .
+  CONTAINER=$(docker create --platform "$PLATFORM" "$BUILDER_NAME")
   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
   docker rm "$CONTAINER"
-fi
 
-# build for linux/arm32:
-if [ ! -d prebuilds/linux-arm ]; then
-  docker build -t bcryptjs-linux-arm-builder -f Dockerfile-arm --build-arg RUN_TESTS="$RUN_TESTS" .
-  CONTAINER=$(docker create --platform linux/arm/v7 bcryptjs-linux-arm-builder)
+  echo -- build for $PLATFORM Alpine --
+  BUILDER_NAME="bcryptjs-${PLATFORM//\/-}-alpine-builder"
+  docker build -t "$BUILDER_NAME" -f Dockerfile-alpine \
+      --build-arg RUN_TESTS="$RUN_TESTS" \
+      --platform "$PLATFORM" .
+  CONTAINER=$(docker create --platform "$PLATFORM" "$BUILDER_NAME")
   docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
   docker rm "$CONTAINER"
-fi
 
-# build for linux/arm64:
-if [ ! -d prebuilds/linux-arm64 ]; then
-  docker build -t bcryptjs-linux-arm64-builder -f Dockerfile-arm64 --build-arg RUN_TESTS="$RUN_TESTS" .
-  CONTAINER=$(docker create --platform linux/arm64/v8 bcryptjs-linux-arm64-builder)
-  docker cp "$CONTAINER:/usr/local/opt/bcrypt-js/prebuilds" .
-  docker rm "$CONTAINER"
-fi
+done
 
 ls -lF prebuilds/
