From 741b834b640be0103cd86e76bac7ce4ea5bb2572 Mon Sep 17 00:00:00 2001 From: Akash Satheesan Date: Tue, 10 Aug 2021 00:05:31 +0530 Subject: [PATCH] feat(ci): armv7 cross builds (#3892) --- .github/workflows/ci.yaml | 41 +++++++++++++++++++++++-------------- ci/build/arch-override.json | 8 ++++++++ ci/build/build-packages.sh | 25 ++++++++++++++++++---- ci/build/nfpm.yaml | 2 +- 4 files changed, 56 insertions(+), 20 deletions(-) create mode 100644 ci/build/arch-override.json diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 18c95834..5e0f2fec 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -234,23 +234,32 @@ jobs: # It is not feasible to cross-compile with CentOS. # Cross-compile notes: To compile native dependencies for arm64, - # we install the aarch64 cross toolchain and then set it as the default + # we install the aarch64/armv7l cross toolchain and then set it as the default # compiler/linker/etc. with the AR/CC/CXX/LINK environment variables. # qemu-user-static on ubuntu-16.04 currently doesn't run Node correctly, - # so we just build with "native"/x86_64 node, then download arm64 node - # and then put it in our release. We can't smoke test the arm64 build this way, + # so we just build with "native"/x86_64 node, then download arm64/armv7l node + # and then put it in our release. We can't smoke test the cross build this way, # but this means we don't need to maintain a self-hosted runner! - package-linux-arm64: - name: Linux ARM64 cross-compile build + package-linux-cross: + name: Linux cross-compile builds needs: build runs-on: ubuntu-16.04 timeout-minutes: 15 + strategy: + matrix: + include: + - prefix: aarch64-linux-gnu + arch: arm64 + - prefix: arm-linux-gnueabihf + arch: armv7l + env: - AR: aarch64-linux-gnu-ar - CC: aarch64-linux-gnu-gcc - CXX: aarch64-linux-gnu-g++ - LINK: aarch64-linux-gnu-g++ - NPM_CONFIG_ARCH: arm64 + AR: ${{ format('{0}-ar', matrix.prefix) }} + CC: ${{ format('{0}-gcc', matrix.prefix) }} + CXX: ${{ format('{0}-g++', matrix.prefix) }} + LINK: ${{ format('{0}-g++', matrix.prefix) }} + NPM_CONFIG_ARCH: ${{ matrix.arch }} + NODE_VERSION: v14.17.4 steps: - uses: actions/checkout@v2 @@ -266,7 +275,9 @@ jobs: echo "$HOME/.local/bin" >> $GITHUB_PATH - name: Install cross-compiler - run: sudo apt install g++-aarch64-linux-gnu + run: sudo apt install $PACKAGE + env: + PACKAGE: ${{ format('g++-{0}', matrix.prefix) }} - name: Download npm package uses: actions/download-artifact@v2 @@ -279,14 +290,14 @@ jobs: - name: Build standalone release run: yarn release:standalone - - name: Replace node with arm64 equivalent + - name: Replace node with cross-compile equivalent run: | - wget https://nodejs.org/dist/v14.17.0/node-v14.17.0-linux-arm64.tar.xz - tar -xf node-v14.17.0-linux-arm64.tar.xz node-v14.17.0-linux-arm64/bin/node --strip-components=2 + wget https://nodejs.org/dist/${NODE_VERSION}/node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz + tar -xf node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}.tar.xz node-${NODE_VERSION}-linux-${NPM_CONFIG_ARCH}/bin/node --strip-components=2 mv ./node ./release-standalone/lib/node - name: Build packages with nfpm - run: yarn package arm64 + run: yarn package ${NPM_CONFIG_ARCH} - name: Upload release artifacts uses: actions/upload-artifact@v2 diff --git a/ci/build/arch-override.json b/ci/build/arch-override.json new file mode 100644 index 00000000..44804dde --- /dev/null +++ b/ci/build/arch-override.json @@ -0,0 +1,8 @@ +{ + "rpm": { + "armv7l": "armhfp" + }, + "deb": { + "armv7l": "armhf" + } +} diff --git a/ci/build/build-packages.sh b/ci/build/build-packages.sh index 8dc33703..a95a80ea 100755 --- a/ci/build/build-packages.sh +++ b/ci/build/build-packages.sh @@ -43,14 +43,31 @@ release_gcp() { cp "./release-packages/$release_name.tar.gz" "./release-gcp/latest/$OS-$ARCH.tar.gz" } +# On some CPU architectures (notably node/uname "armv7l", default on Raspberry Pis), +# different package managers have different labels for the same CPU (deb=armhf, rpm=armhfp). +# This function parses arch-override.json and returns the overriden arch on platforms +# with alternate labels, or the same arch otherwise. +get_nfpm_arch() { + if jq -re ".${PKG_FORMAT}.${ARCH}" ./ci/build/arch-override.json > /dev/null; then + jq -re ".${PKG_FORMAT}.${ARCH}" ./ci/build/arch-override.json + else + echo "$ARCH" + fi +} + # Generates deb and rpm packages. release_nfpm() { local nfpm_config - nfpm_config="$(envsubst < ./ci/build/nfpm.yaml)" - # The underscores are convention for .deb. - nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server_${VERSION}_$ARCH.deb" - nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server-$VERSION-$ARCH.rpm" + PKG_FORMAT="deb" + NFPM_ARCH="$(get_nfpm_arch)" + nfpm_config="$(envsubst < ./ci/build/nfpm.yaml)" + nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server_${VERSION}_${NFPM_ARCH}.deb" + + PKG_FORMAT="rpm" + NFPM_ARCH="$(get_nfpm_arch)" + nfpm_config="$(envsubst < ./ci/build/nfpm.yaml)" + nfpm pkg -f <(echo "$nfpm_config") --target "release-packages/code-server-$VERSION-$NFPM_ARCH.rpm" } main "$@" diff --git a/ci/build/nfpm.yaml b/ci/build/nfpm.yaml index 7aa51f9e..93142d19 100644 --- a/ci/build/nfpm.yaml +++ b/ci/build/nfpm.yaml @@ -1,5 +1,5 @@ name: "code-server" -arch: "${ARCH}" +arch: "${NFPM_ARCH}" platform: "linux" version: "v${VERSION}" section: "devel"