From aff1c2b008f775c637c40b9d6c1ea54ce6dd64b4 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 16:22:34 -0300 Subject: [PATCH 01/11] switch Linux build over to use configured docker image Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- .github/workflows/ci.yml | 63 +++++++++++++++++++++++++++--- script/electron-builder-linux.yml | 2 +- script/package-debian.ts | 5 ++- script/package-electron-builder.ts | 3 +- script/package-redhat.ts | 5 ++- 5 files changed, 67 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9782bd58ca6..618bd53f2cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,7 @@ jobs: build: name: ${{ matrix.friendlyName }} ${{ matrix.arch }} runs-on: ${{ matrix.os }} + container: ${{ matrix.image }} permissions: contents: write strategy: @@ -51,24 +52,76 @@ jobs: friendlyName: Windows - os: ubuntu-20.04 friendlyName: Ubuntu + image: ubuntu:18.04 + arch: x64 + environment: + AS: as + STRIP: strip + AR: ar + CC: gcc + CPP: cpp + CXX: g++ + LD: ld + FC: gfortran + PKG_CONFIG_PATH: /usr/lib/x86_64-linux-gnu/pkgconfig exclude: - os: ubuntu-20.04 arch: arm64 timeout-minutes: 60 env: RELEASE_CHANNEL: ${{ inputs.environment }} + AS: ${{ matrix.environment.AS }} + STRIP: ${{ matrix.environment.STRIP }} + AR: ${{ matrix.environment.AR }} + CC: ${{ matrix.environment.CC }} + CPP: ${{ matrix.environment.CPP }} + CXX: ${{ matrix.environment.CXX }} + LD: ${{ matrix.environment.LD }} + FC: ${{ matrix.environment.FC }} + PKG_CONFIG_PATH: ${{ matrix.environment.PKG_CONFIG_PATH }} steps: + - name: Install dependencies into dockerfile on Ubuntu + if: matrix.friendlyName == 'Ubuntu' + run: | + # ubuntu dockerfile is very minimal (only 122 packages are installed) + # add dependencies expected by scripts + apt update + apt install -y software-properties-common lsb-release \ + sudo wget curl build-essential jq autoconf automake \ + pkg-config ca-certificates rpm + # install new enough git to run actions/checkout + sudo add-apt-repository ppa:git-core/ppa -y + sudo apt update + sudo apt install -y git + # avoid "fatal: detected dubious ownership in repository at '/__w/shiftkey/desktop'" error + git config --global --add safe.directory '*' + - name: Add additional dependencies for Ubuntu x64 + if: ${{ matrix.friendlyName == 'Ubuntu' && matrix.arch == 'x64' }} + run: | + # add electron unit test dependencies + sudo apt install -y libasound2 libatk-bridge2.0-0 libatk1.0-0 \ + libatspi2.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libdrm2 \ + libexpat1 libgbm1 libgcc1 libglib2.0-0 libgtk-3-0 libnspr4 \ + libnss3 libpango-1.0-0 libx11-6 libxcb1 libxcomposite1 \ + libxdamage1 libxext6 libxfixes3 libxkbcommon0 libxrandr2 \ + libsecret-1-0 - uses: actions/checkout@v3 with: repository: ${{ inputs.repository || github.repository }} ref: ${{ inputs.ref }} submodules: recursive - name: Use Node.js ${{ matrix.node }} + if: matrix.friendlyName != 'Ubuntu' uses: actions/setup-node@v3 with: node-version: ${{ matrix.node }} cache: yarn - + - name: Install unofficial-builds Node.js ${{ matrix.node }} on Ubuntu + if: matrix.friendlyName == 'Ubuntu' + run: | + # this version supports older GLIBC (official builds required a minimum of GLIBC 2.28) + curl -sL 'https://unofficial-builds.nodejs.org/download/release/v${{ matrix.node }}/node-v${{ matrix.node }}-linux-x64-glibc-217.tar.xz' | xzcat | sudo tar -vx --strip-components=1 -C /usr/local/ + sudo npm install --global yarn # This step can be removed as soon as official Windows arm64 builds are published: # https://github.com/nodejs/build/issues/2450#issuecomment-705853342 - name: Get NodeJS node-gyp lib for Windows arm64 @@ -81,12 +134,10 @@ jobs: run: yarn env: npm_config_arch: ${{ matrix.arch }} - TARGET_ARCH: ${{ matrix.arch }} - name: Build production app run: yarn build:prod env: npm_config_arch: ${{ matrix.arch }} - TARGET_ARCH: ${{ matrix.arch }} - name: Prepare testing environment if: matrix.arch == 'x64' run: yarn test:setup @@ -98,11 +149,13 @@ jobs: run: yarn test:script - name: Package application run: yarn run package - if: ${{ matrix.os == 'ubuntu-20.04' && matrix.arch == 'x64' }} + if: ${{ matrix.friendlyName == 'Ubuntu' }} + env: + npm_config_arch: ${{ matrix.arch }} - name: Create Release uses: softprops/action-gh-release@v1 if: - ${{ matrix.os == 'ubuntu-20.04' && startsWith(github.ref, + ${{ matrix.friendlyName == 'Ubuntu' && startsWith(github.ref, 'refs/tags/') }} with: files: | diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index bcaae41ee82..c40d57c7e98 100644 --- a/script/electron-builder-linux.yml +++ b/script/electron-builder-linux.yml @@ -1,4 +1,4 @@ -artifactName: 'GitHubDesktop-${os}-${version}.${ext}' +artifactName: 'GitHubDesktop-${os}-${arch}-${version}.${ext}' linux: category: 'GNOME;GTK;Development' packageCategory: 'GNOME;GTK;Development' diff --git a/script/package-debian.ts b/script/package-debian.ts index 9a918473070..b184481843d 100644 --- a/script/package-debian.ts +++ b/script/package-debian.ts @@ -10,7 +10,8 @@ import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return 'arm64' case 'arm': @@ -107,7 +108,7 @@ export async function packageDebian(): Promise { const oldPath = files[0] - const newFileName = `GitHubDesktop-linux-${getVersion()}.deb` + const newFileName = `GitHubDesktop-linux-${getArchitecture()}-${getVersion()}.deb` const newPath = join(distRoot, newFileName) await rename(oldPath, newPath) diff --git a/script/package-electron-builder.ts b/script/package-electron-builder.ts index 6292c28b9f4..2f56e73fba5 100644 --- a/script/package-electron-builder.ts +++ b/script/package-electron-builder.ts @@ -10,7 +10,8 @@ const globPromise = promisify(glob) import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return '--arm64' case 'arm': diff --git a/script/package-redhat.ts b/script/package-redhat.ts index 37bd3819293..61fe4a1162e 100644 --- a/script/package-redhat.ts +++ b/script/package-redhat.ts @@ -10,7 +10,8 @@ import { getVersion } from '../app/package-info' import { getDistPath, getDistRoot } from './dist-info' function getArchitecture() { - switch (process.arch) { + const arch = process.env.npm_config_arch || process.arch + switch (arch) { case 'arm64': return 'aarch64' case 'arm': @@ -103,7 +104,7 @@ export async function packageRedhat(): Promise { const oldPath = files[0] - const newFileName = `GitHubDesktop-linux-${getVersion()}.rpm` + const newFileName = `GitHubDesktop-linux-${getArchitecture()}-${getVersion()}.rpm` const newPath = join(distRoot, newFileName) await rename(oldPath, newPath) From 3662c1802cda3d3f9b93ef96159b7fb6f3eb7d27 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 16:33:17 -0300 Subject: [PATCH 02/11] update to latest Node 18 release to access version which only requires GLIBC 17 Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 618bd53f2cf..1edb7872fa9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,7 +42,7 @@ jobs: strategy: fail-fast: false matrix: - node: [18.14.0] + node: [18.16.1] os: [macos-11, windows-2019, ubuntu-20.04] arch: [x64, arm64] include: From 8a37230a21c4ece14c6734422626f4a1d7f631da Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 16:36:12 -0300 Subject: [PATCH 03/11] add comment to remember why this version is special alter --- .github/workflows/ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1edb7872fa9..0b4a56dc2c0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -120,6 +120,8 @@ jobs: if: matrix.friendlyName == 'Ubuntu' run: | # this version supports older GLIBC (official builds required a minimum of GLIBC 2.28) + # this will likely break if you bump the `matrix.node` version - need to explore options here + # curl -sL 'https://unofficial-builds.nodejs.org/download/release/v${{ matrix.node }}/node-v${{ matrix.node }}-linux-x64-glibc-217.tar.xz' | xzcat | sudo tar -vx --strip-components=1 -C /usr/local/ sudo npm install --global yarn # This step can be removed as soon as official Windows arm64 builds are published: From 40645c7831566f68b97c929489728e885d780282 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:02:50 -0300 Subject: [PATCH 04/11] upload artifacts to assist with testing CI outputs --- .github/workflows/ci.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0b4a56dc2c0..cffbd0b8223 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -168,3 +168,13 @@ jobs: draft: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Upload output artifacts + uses: actions/upload-artifact@v3 + if: matrix.friendlyName == 'Ubuntu' + with: + name: ${{ matrix.friendlyName }}-${{ matrix.arch }}-artifacts + path: | + dist/*.AppImage + dist/*.deb + dist/*.rpm + retention-days: 5 From a4318faa52a1d3ad91c552c8eda1b8edfb3b3be8 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:15:47 -0300 Subject: [PATCH 05/11] update comment on unofficial Node builds --- .github/workflows/ci.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cffbd0b8223..50c3cb07ed3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -119,8 +119,11 @@ jobs: - name: Install unofficial-builds Node.js ${{ matrix.node }} on Ubuntu if: matrix.friendlyName == 'Ubuntu' run: | - # this version supports older GLIBC (official builds required a minimum of GLIBC 2.28) - # this will likely break if you bump the `matrix.node` version - need to explore options here + # This version supports older GLIBC (official builds required a minimum of GLIBC 2.28) + # this might break if you bump the `matrix.node` version - ensure you are on the latest version + # of which ever major/minor release which should have this variant available + # + # See https://github.com/nodejs/unofficial-builds/ for more information on these versions. # curl -sL 'https://unofficial-builds.nodejs.org/download/release/v${{ matrix.node }}/node-v${{ matrix.node }}-linux-x64-glibc-217.tar.xz' | xzcat | sudo tar -vx --strip-components=1 -C /usr/local/ sudo npm install --global yarn From c29e70c77dba7b7f8290a39b069a265a19730f52 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:23:51 -0300 Subject: [PATCH 06/11] additional cleanup to build step to choose correct architecture Co-authored-by: theofficialgman <28281419+theofficialgman@users.noreply.github.com> --- script/build.ts | 6 +++++- script/dist-info.ts | 15 +++++---------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/script/build.ts b/script/build.ts index cebf37569b7..2889e499891 100755 --- a/script/build.ts +++ b/script/build.ts @@ -144,6 +144,10 @@ function packageApp() { return targetArch } + if (targetArch === 'arm') { + return 'armv7l' + } + throw new Error( `Building Desktop for architecture '${targetArch}' is not supported` ) @@ -175,7 +179,7 @@ function packageApp() { return packager({ name: getExecutableName(), platform: toPackagePlatform(process.platform), - arch: toPackageArch(process.env.TARGET_ARCH), + arch: toPackageArch(process.env.npm_config_arch), asar: false, // TODO: Probably wanna enable this down the road. out: getDistRoot(), icon, diff --git a/script/dist-info.ts b/script/dist-info.ts index 864330225a0..c40d2a4945a 100644 --- a/script/dist-info.ts +++ b/script/dist-info.ts @@ -114,18 +114,13 @@ export const getChannel = () => export function getDistArchitecture(): 'arm64' | 'x64' | 'armv7l' { // If a specific npm_config_arch is set, we use that one instead of the OS arch (to support cross compilation) - if ( - process.env.npm_config_arch === 'arm64' || - process.env.npm_config_arch === 'x64' || - process.env.npm_config_arch === 'armv7l' - ) { - return process.env.npm_config_arch - } + const arch = process.env.npm_config_arch || process.arch - if (process.arch === 'arm64') { - return 'arm64' + if (arch === 'arm64' || arch === 'x64' || arch === 'armv7l') { + return arch } - if (process.arch === 'armv7l') { + + if (arch === 'arm') { return 'armv7l' } From 68b7d69e4172b915c66438af44ca95a4da6ecf9d Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:38:05 -0300 Subject: [PATCH 07/11] inline input and follow pattern in other places for resolving architecture --- script/build.ts | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/script/build.ts b/script/build.ts index 2889e499891..af5ac33bf7d 100755 --- a/script/build.ts +++ b/script/build.ts @@ -3,7 +3,6 @@ import * as path from 'path' import * as cp from 'child_process' -import * as os from 'os' import packager, { OfficialArch, OsxNotarizeOptions } from 'electron-packager' import frontMatter from 'front-matter' import { externals } from '../app/webpack.common' @@ -131,25 +130,19 @@ function packageApp() { ) } - const toPackageArch = (targetArch: string | undefined): OfficialArch => { - if (targetArch === undefined) { - targetArch = os.arch() - } + const getPackageArch = (): OfficialArch => { + const arch = process.env.npm_config_arch || process.arch - if ( - targetArch === 'arm64' || - targetArch === 'x64' || - targetArch === 'armv7l' - ) { - return targetArch + if (arch === 'arm64' || arch === 'x64' || arch === 'armv7l') { + return arch } - if (targetArch === 'arm') { + if (arch === 'arm') { return 'armv7l' } throw new Error( - `Building Desktop for architecture '${targetArch}' is not supported` + `Building Desktop for architecture '${arch}' is not supported` ) } @@ -179,7 +172,7 @@ function packageApp() { return packager({ name: getExecutableName(), platform: toPackagePlatform(process.platform), - arch: toPackageArch(process.env.npm_config_arch), + arch: getPackageArch(), asar: false, // TODO: Probably wanna enable this down the road. out: getDistRoot(), icon, From 5c52654f56e53552b7f4281a9da887c5e7c311d1 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:56:33 -0300 Subject: [PATCH 08/11] update getPackageArch to better reflect input parameters --- script/build.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/script/build.ts b/script/build.ts index af5ac33bf7d..3933a638f80 100755 --- a/script/build.ts +++ b/script/build.ts @@ -3,7 +3,7 @@ import * as path from 'path' import * as cp from 'child_process' -import packager, { OfficialArch, OsxNotarizeOptions } from 'electron-packager' +import packager, { OsxNotarizeOptions } from 'electron-packager' import frontMatter from 'front-matter' import { externals } from '../app/webpack.common' @@ -130,10 +130,10 @@ function packageApp() { ) } - const getPackageArch = (): OfficialArch => { + const getPackageArch = (): 'arm64' | 'x64' | 'armv7l' => { const arch = process.env.npm_config_arch || process.arch - if (arch === 'arm64' || arch === 'x64' || arch === 'armv7l') { + if (arch === 'arm64' || arch === 'x64') { return arch } From 1b0ffe5da5f7f2d9bb40beb84e678016d732b185 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 17:59:27 -0300 Subject: [PATCH 09/11] add context to error message --- script/build.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/build.ts b/script/build.ts index 3933a638f80..9b60e36e85b 100755 --- a/script/build.ts +++ b/script/build.ts @@ -142,7 +142,7 @@ function packageApp() { } throw new Error( - `Building Desktop for architecture '${arch}' is not supported` + `Building Desktop for architecture '${arch}' is not supported. Currently these architectures are supported: arm, arm64, x64` ) } From 033fb7150054c641340527f87d0057d13dc46439 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 18:28:02 -0300 Subject: [PATCH 10/11] lift npm_config_arch up to global environment variables --- .github/workflows/ci.yml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 50c3cb07ed3..e63fd32d31d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -79,6 +79,7 @@ jobs: LD: ${{ matrix.environment.LD }} FC: ${{ matrix.environment.FC }} PKG_CONFIG_PATH: ${{ matrix.environment.PKG_CONFIG_PATH }} + npm_config_arch: ${{ matrix.arch }} steps: - name: Install dependencies into dockerfile on Ubuntu if: matrix.friendlyName == 'Ubuntu' @@ -137,12 +138,8 @@ jobs: run: echo version=$(jq -r ".version" app/package.json) >> $GITHUB_OUTPUT - name: Install and build dependencies run: yarn - env: - npm_config_arch: ${{ matrix.arch }} - name: Build production app run: yarn build:prod - env: - npm_config_arch: ${{ matrix.arch }} - name: Prepare testing environment if: matrix.arch == 'x64' run: yarn test:setup @@ -155,8 +152,6 @@ jobs: - name: Package application run: yarn run package if: ${{ matrix.friendlyName == 'Ubuntu' }} - env: - npm_config_arch: ${{ matrix.arch }} - name: Create Release uses: softprops/action-gh-release@v1 if: From 47e1aa6db01759f41cb34c8bfc2a714b451e2fc6 Mon Sep 17 00:00:00 2001 From: Brendan Forster Date: Sun, 9 Jul 2023 18:35:55 -0300 Subject: [PATCH 11/11] wrorkaround for Windows ARM builds requiring a specific version of Node --- .github/workflows/ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e63fd32d31d..33549d773d0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -130,9 +130,12 @@ jobs: sudo npm install --global yarn # This step can be removed as soon as official Windows arm64 builds are published: # https://github.com/nodejs/build/issues/2450#issuecomment-705853342 + # + # This version is pinned to 18.16.0 as the later version does not have the required + # `win-arm64/node.lib` output that we can consume in this CI build. - name: Get NodeJS node-gyp lib for Windows arm64 if: ${{ matrix.os == 'windows-2019' && matrix.arch == 'arm64' }} - run: .\script\download-nodejs-win-arm64.ps1 ${{ matrix.node }} + run: .\script\download-nodejs-win-arm64.ps1 18.16.0 - name: Get app version id: version run: echo version=$(jq -r ".version" app/package.json) >> $GITHUB_OUTPUT