diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fad3510681d..c6c372d082f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,6 +41,7 @@ jobs: build: name: ${{ matrix.friendlyName }} ${{ matrix.arch }} runs-on: ${{ matrix.os }} + container: ${{ matrix.image }} permissions: contents: write strategy: @@ -55,14 +56,61 @@ 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 }} + npm_config_arch: ${{ matrix.arch }} steps: - - uses: actions/checkout@v4 + - 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 }} @@ -71,20 +119,26 @@ jobs: with: python-version: '3.11' - name: Use Node.js ${{ env.NODE_VERSION }} + if: matrix.friendlyName != 'Ubuntu' uses: actions/setup-node@v4 with: node-version: ${{ env.NODE_VERSION }} 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) + # 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 - name: Install and build dependencies 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 +152,11 @@ 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' }} - 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: | @@ -113,3 +167,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 diff --git a/script/build.ts b/script/build.ts index dcc3bb7cdf7..e119c1f5780 100755 --- a/script/build.ts +++ b/script/build.ts @@ -3,8 +3,7 @@ import * as path from 'path' import * as cp from 'child_process' -import * as os from 'os' -import packager, { OfficialArch, OsxNotarizeOptions } from 'electron-packager' +import packager, { OsxNotarizeOptions } from 'electron-packager' import frontMatter from 'front-matter' import { externals } from '../app/webpack.common' @@ -131,21 +130,19 @@ function packageApp() { ) } - const toPackageArch = (targetArch: string | undefined): OfficialArch => { - if (targetArch === undefined) { - targetArch = os.arch() + const getPackageArch = (): 'arm64' | 'x64' | 'armv7l' => { + const arch = process.env.npm_config_arch || process.arch + + if (arch === 'arm64' || arch === 'x64') { + return arch } - if ( - targetArch === 'arm64' || - targetArch === 'x64' || - targetArch === 'armv7l' - ) { - return targetArch + if (arch === 'arm') { + return 'armv7l' } throw new Error( - `Building Desktop for architecture '${targetArch}' is not supported` + `Building Desktop for architecture '${arch}' is not supported. Currently these architectures are supported: arm, arm64, x64` ) } @@ -174,7 +171,7 @@ function packageApp() { return packager({ name: getExecutableName(), platform: toPackagePlatform(process.platform), - arch: toPackageArch(process.env.TARGET_ARCH), + arch: getPackageArch(), 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 420444f7448..459f01db905 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 === 'arm') { + + if (arch === 'arm') { return 'armv7l' } diff --git a/script/electron-builder-linux.yml b/script/electron-builder-linux.yml index f73156cbadb..77203eb0b46 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)