diff --git a/.github/actions/build-linux-arm/action.yml b/.github/actions/build-linux-arm/action.yml new file mode 100644 index 00000000..7098d345 --- /dev/null +++ b/.github/actions/build-linux-arm/action.yml @@ -0,0 +1,113 @@ +name: 'Build Linux ARM' +description: 'Cross-compiles Hyper app for ARMv7l and ARM64 using arm-runner' +inputs: + node-version: + description: 'Node.js version to use' + required: true + matrix-name: + description: 'Matrix name (arch)' + required: true + matrix-cpu: + description: 'CPU architecture' + required: true + matrix-image: + description: 'Base OS image for ARM emulation' + required: true + upload-artifact: + description: 'Whether to upload artifacts' + required: false + default: 'true' +runs: + using: 'composite' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ inputs.node-version }} + + - name: Fix node-gyp and Python + shell: bash + run: | + python3 -m pip install packaging setuptools + + - name: Get yarn cache directory path + shell: bash + id: yarn-cache-dir-path + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v4 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install dependencies and tools + shell: bash + run: | + yarn install + sudo apt update + sudo apt install libarchive-tools + + - name: Compile + shell: bash + run: yarn run build + + - name: Rebuild node-pty for ARM + uses: pguyot/arm-runner-action@v2.6.5 + with: + image_additional_mb: 2000 + base_image: ${{ inputs.matrix-image }} + cpu: ${{ inputs.matrix-cpu }} + shell: bash + copy_artifact_path: target/node_modules/node-pty + copy_artifact_dest: target/node_modules + commands: | + wget https://nodejs.org/dist/v18.16.0/node-v18.16.0-linux-${{ inputs.matrix-name }}.tar.xz + tar -xJf node-v18.16.0-linux-${{ inputs.matrix-name }}.tar.xz + sudo cp node-v18.16.0-linux-${{ inputs.matrix-name }}/* /usr/local/ -R + npm run rebuild-node-pty + + - name: Chown rebuilt node-pty + shell: bash + run: | + sudo chown -R $USER:$USER target/node_modules/node-pty + + - name: Prepare v8 snapshot (only armv7l) + if: ${{ inputs.matrix-name == 'armv7l' }} + shell: bash + run: | + sudo dpkg --add-architecture i386 + sudo apt update + sudo apt install -y libglib2.0-0:i386 libexpat1:i386 libgcc-s1:i386 + npm_config_arch=armv7l yarn run v8-snapshot:arch + + - name: Build final Electron App for ARM + shell: bash + run: | + yarn run electron-builder -l deb rpm AppImage pacman --${{ inputs.matrix-name }} -c electron-builder-linux-ci.json + env: + GH_TOKEN: ${{ env.GH_TOKEN }} + + - name: Archive Build Artifacts + if: ${{ inputs.upload-artifact == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: hyper-linux-${{ inputs.matrix-name }} + path: | + dist/*.snap + dist/*.AppImage + dist/*.deb + dist/*.rpm + dist/*.pacman + +# - name: Run E2E Tests on Linux +# if: runner.os == 'Linux' +# uses: GabrielBB/xvfb-action@v1.7 +# with: +# run: | +# yarn run test +# \ No newline at end of file diff --git a/.github/actions/build/action.yml b/.github/actions/build/action.yml new file mode 100644 index 00000000..b1a0bc0c --- /dev/null +++ b/.github/actions/build/action.yml @@ -0,0 +1,169 @@ +name: 'Build' +description: 'Builds, tests, and packages the app for release' +inputs: + node-version: + description: 'Node.js version to use' + required: true + matrix-name: + description: 'Matrix Name' + required: true + matrix-os: + description: 'Matrix OS' + required: true + upload-artifact: + description: 'Whether to upload artifacts' + required: false + default: 'true' +runs: + using: 'composite' + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Use Node.js ${{ env.NODE_VERSION }} + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Fix node-gyp and Python + shell: bash + run: | + if [[ "$RUNNER_OS" == "macOS" ]]; then + brew install python-setuptools python-packaging + else + python3 -m pip install $EXTRA_ARGS packaging setuptools + fi + + - name: Get yarn cache directory path + shell: bash + id: yarn-cache-dir-path + run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT + + - uses: actions/cache/restore@v4 + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install + shell: bash + run: yarn install + env: + npm_config_node_gyp: ${{ github.workspace }}${{ runner.os == 'Windows' && '\node_modules\node-gyp\bin\node-gyp.js' || '/node_modules/node-gyp/bin/node-gyp.js' }} + + - name: Install libarchive-tools + shell: bash + if: runner.os == 'Linux' + run: | + sudo apt update + sudo apt install libarchive-tools + + - name: Lint and Run Unit Tests + shell: bash + run: yarn run test + + - name: Getting Build Icon + shell: bash + if: github.ref == 'refs/heads/canary' || github.base_ref == 'canary' + run: | + cp build/canary.ico build/icon.ico + cp build/canary.icns build/icon.icns + + - name: Build + shell: bash + run: | + if [ -z "$CSC_LINK" ] ; then unset CSC_LINK ; fi + if [ -z "$CSC_KEY_PASSWORD" ] ; then unset CSC_KEY_PASSWORD ; fi + if [ -z "$WIN_CSC_LINK" ] ; then unset WIN_CSC_LINK ; fi + if [ -z "$WIN_CSC_KEY_PASSWORD" ] ; then unset WIN_CSC_KEY_PASSWORD ; fi + if [ -z "$APPLE_ID" ] ; then unset APPLE_ID ; fi + if [ -z "$APPLE_APP_SPECIFIC_PASSWORD" ] ; then unset APPLE_APP_SPECIFIC_PASSWORD ; fi + yarn run dist + env: + GH_TOKEN: ${{ env.GITHUB_TOKEN }} + CSC_LINK: ${{ env.MAC_CERT_P12_BASE64 }} + CSC_KEY_PASSWORD: ${{ env.MAC_CERT_P12_PASSWORD }} + WIN_CSC_LINK: ${{ env.WIN_CERT_P12_BASE64 }} + WIN_CSC_KEY_PASSWORD: ${{ env.WIN_CERT_P12_PASSWORD }} + APPLE_ID: ${{ env.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ env.APPLE_PASSWORD }} + + - name: Archive Build Artifacts + uses: actions/upload-artifact@v4 + with: + name: hyper-${{ runner.os }}-${{ inputs.matrix-name }} + path: | + dist/*.dmg + dist/*.snap + dist/*.AppImage + dist/*.deb + dist/*.pacman + dist/*.exe + + - name: Run E2E Tests + shell: bash + if: runner.os != 'Linux' + run: yarn run test:e2e --verbose + + - name: Run E2E Tests on Linux + if: runner.os == 'Linux' + uses: GabrielBB/xvfb-action@v1.7 + with: + run: | + yarn run test:e2e + env: + SHELL: /bin/bash + DEBUG: "pw:browser*" + + - name: Archive E2E test screenshot + uses: actions/upload-artifact@v4 + with: + name: e2e-${{ inputs.matrix-os }}-${{ strategy.job-index }} + path: dist/tmp/*.png + + - name: Save the pr number in an artifact + shell: bash + if: github.event_name == 'pull_request' + env: + PR_NUM: ${{ github.event.number }} + run: echo $PR_NUM > pr_num.txt + + - name: Upload the pr num + uses: actions/upload-artifact@v4 + if: github.event_name == 'pull_request' + with: + name: pr_num + path: ./pr_num.txt + + - uses: actions/cache/save@v4 + if: github.event_name == 'push' + with: + path: ${{ steps.yarn-cache-dir-path.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} + + - name: Archive Build Artifacts + if: ${{ inputs.upload-artifact == 'true' }} + uses: actions/upload-artifact@v4 + with: + name: hyper-${{ runner.os }} + path: | + dist/*.dmg + dist/*.snap + dist/*.AppImage + dist/*.deb + dist/*.pacman + dist/*.exe + +# - name: Run E2E Tests (non-Linux) +# if: runner.os != 'Linux' +# shell: bash +# run: yarn run test:e2e --verbose +# +# - name: Run E2E Tests on Linux +# if: runner.os == 'Linux' +# uses: GabrielBB/xvfb-action@v1.7 +# with: +# run: | +# yarn run test +# \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..65e90507 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,117 @@ +name: Node CI +on: + push: + branches: + workflow_dispatch: +defaults: + run: + shell: bash + +concurrency: + group: ci-${{ github.ref }} + cancel-in-progress: true + +env: + NODE_VERSION: 20.11.0 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }} + CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_P12_PASSWORD }} + WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12_BASE64 }} + WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_P12_PASSWORD }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + +jobs: + build-ubuntu: + name: Build Ubuntu + runs-on: ubuntu-latest + concurrency: + group: build-ubuntu-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: ubuntu-latest + matrix-name: ubuntu + upload-artifact: false + + build-macos: + name: Build macOS + runs-on: macos-latest + concurrency: + group: build-macos-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: macos-latest + matrix-name: macos + upload-artifact: false + + build-windows: + name: Build Windows + runs-on: windows-latest + concurrency: + group: build-win-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: windows-latest + matrix-name: win + upload-artifact: false + + # ARM Linux: + + build-linux-armv7l: + name: Build Linux ARMv7l + runs-on: ubuntu-latest + concurrency: + group: build-linux-armv7l-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build ARMv7l + uses: ./.github/actions/build-linux-arm + with: + node-version: ${{ env.NODE_VERSION }} + matrix-name: armv7l + matrix-cpu: cortex-a8 + matrix-image: raspios_lite:latest + upload-artifact: false + + build-linux-arm64: + name: Build Linux ARM64 + runs-on: ubuntu-latest + concurrency: + group: build-linux-arm64-${{ github.ref }} + cancel-in-progress: false + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build ARM64 + uses: ./.github/actions/build-linux-arm + with: + node-version: ${{ env.NODE_VERSION }} + matrix-name: arm64 + matrix-cpu: cortex-a53 + matrix-image: raspios_lite_arm64:latest + upload-artifact: false diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index ecd69d90..00000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,199 +0,0 @@ -name: Node CI -on: - push: - branches: - workflow_dispatch: -defaults: - run: - shell: bash -env: - NODE_VERSION: 20.11.0 -jobs: - build: - runs-on: ${{matrix.os}} - strategy: - matrix: - include: - - os: macos-latest - name: macos - - os: ubuntu-latest - name: ubuntu - - os: windows-latest - name: win - fail-fast: false - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Fix node-gyp and Python - run: | - if [[ "$RUNNER_OS" == "macOS" ]]; then - brew install python-setuptools python-packaging - else - python3 -m pip install $EXTRA_ARGS packaging setuptools - fi - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v4 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install - run: yarn install - env: - npm_config_node_gyp: ${{ github.workspace }}${{ runner.os == 'Windows' && '\node_modules\node-gyp\bin\node-gyp.js' || '/node_modules/node-gyp/bin/node-gyp.js' }} - - name: Install libarchive-tools - if: runner.os == 'Linux' - run: | - sudo apt update - sudo apt install libarchive-tools - - name: Lint and Run Unit Tests - run: yarn run test - - name: Getting Build Icon - if: github.ref == 'refs/heads/canary' || github.base_ref == 'canary' - run: | - cp build/canary.ico build/icon.ico - cp build/canary.icns build/icon.icns - - name: Build - run: | - if [ -z "$CSC_LINK" ] ; then unset CSC_LINK ; fi - if [ -z "$CSC_KEY_PASSWORD" ] ; then unset CSC_KEY_PASSWORD ; fi - if [ -z "$WIN_CSC_LINK" ] ; then unset WIN_CSC_LINK ; fi - if [ -z "$WIN_CSC_KEY_PASSWORD" ] ; then unset WIN_CSC_KEY_PASSWORD ; fi - if [ -z "$APPLE_ID" ] ; then unset APPLE_ID ; fi - if [ -z "$APPLE_APP_SPECIFIC_PASSWORD" ] ; then unset APPLE_APP_SPECIFIC_PASSWORD ; fi - yarn run dist - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }} - CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_P12_PASSWORD }} - WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12_BASE64 }} - WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_P12_PASSWORD }} - APPLE_ID: ${{ secrets.APPLE_ID }} - APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} - - name: Archive Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: hyper-${{ runner.os }}-${{ matrix.name }} - path: | - dist/*.dmg - dist/*.snap - dist/*.AppImage - dist/*.deb - dist/*.pacman - dist/*.exe - - name: Run E2E Tests - if: runner.os != 'Linux' - run: yarn run test:e2e --verbose - - name: Run E2E Tests on Linux - if: runner.os == 'Linux' - uses: GabrielBB/xvfb-action@v1.7 - with: - run: | - yarn run test:e2e - env: - SHELL: /bin/bash - DEBUG: "pw:browser*" - - name: Archive E2E test screenshot - uses: actions/upload-artifact@v4 - with: - name: e2e-${{ matrix.os }}-${{ strategy.job-index }} - path: dist/tmp/*.png - - name: Save the pr number in an artifact - if: github.event_name == 'pull_request' - env: - PR_NUM: ${{ github.event.number }} - run: echo $PR_NUM > pr_num.txt - - name: Upload the pr num - uses: actions/upload-artifact@v4 - if: github.event_name == 'pull_request' - with: - name: pr_num - path: ./pr_num.txt - - uses: actions/cache/save@v4 - if: github.event_name == 'push' - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} - - build-linux-arm: - runs-on: ubuntu-latest - strategy: - matrix: - include: - - name: armv7l - cpu: cortex-a8 - image: raspios_lite:latest - - name: arm64 - cpu: cortex-a53 - image: raspios_lite_arm64:latest - fail-fast: false - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Use Node.js ${{ env.NODE_VERSION }} - uses: actions/setup-node@v4 - with: - node-version: ${{ env.NODE_VERSION }} - - name: Fix node-gyp and Python - run: python3 -m pip install packaging setuptools - - name: Get yarn cache directory path - id: yarn-cache-dir-path - run: echo "dir=$(yarn cache dir)" >> $GITHUB_OUTPUT - - uses: actions/cache/restore@v4 - with: - path: ${{ steps.yarn-cache-dir-path.outputs.dir }} - key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock', 'app/yarn.lock') }} - restore-keys: | - ${{ runner.os }}-yarn- - - name: Install - run: | - yarn install - sudo apt update - sudo apt install libarchive-tools - - name: Compile - run: yarn run build - - name: rebuild node-pty - uses: pguyot/arm-runner-action@v2.6.5 - with: - image_additional_mb: 2000 - base_image: ${{ matrix.image }} - cpu: ${{ matrix.cpu }} - shell: bash - copy_artifact_path: target/node_modules/node-pty - copy_artifact_dest: target/node_modules - commands: | - wget https://nodejs.org/dist/v18.16.0/node-v18.16.0-linux-${{ matrix.name }}.tar.xz - tar -xJf node-v18.16.0-linux-${{ matrix.name }}.tar.xz - sudo cp node-v18.16.0-linux-${{ matrix.name }}/* /usr/local/ -R - npm run rebuild-node-pty - - name: chown node-pty - run: | - sudo chown -R $USER:$USER target/node_modules/node-pty - - name: Prepare v8 snapshot - if: matrix.name == 'armv7l' - run: | - sudo dpkg --add-architecture i386 - sudo apt update - sudo apt install -y libglib2.0-0:i386 libexpat1:i386 libgcc-s1:i386 - npm_config_arch=armv7l yarn run v8-snapshot:arch - - name: Build - run: yarn run electron-builder -l deb rpm AppImage pacman --${{ matrix.name }} -c electron-builder-linux-ci.json - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Archive Build Artifacts - uses: actions/upload-artifact@v4 - with: - name: hyper-${{ runner.os }}-${{ matrix.name }} - path: | - dist/*.snap - dist/*.AppImage - dist/*.deb - dist/*.rpm - dist/*.pacman diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..7f0414a7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,137 @@ +name: Create Release + +on: + push: + tags: + - "v*" + workflow_dispatch: + +concurrency: + group: release-${{ github.ref }} + cancel-in-progress: true + +env: + NODE_VERSION: 20.11.0 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CSC_LINK: ${{ secrets.MAC_CERT_P12_BASE64 }} + CSC_KEY_PASSWORD: ${{ secrets.MAC_CERT_P12_PASSWORD }} + WIN_CSC_LINK: ${{ secrets.WIN_CERT_P12_BASE64 }} + WIN_CSC_KEY_PASSWORD: ${{ secrets.WIN_CERT_P12_PASSWORD }} + APPLE_ID: ${{ secrets.APPLE_ID }} + APPLE_APP_SPECIFIC_PASSWORD: ${{ secrets.APPLE_PASSWORD }} + +jobs: + build-ubuntu: + name: Build Ubuntu + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: ubuntu-latest + matrix-name: ubuntu + upload-artifact: true + + build-macos: + name: Build macOS + runs-on: macos-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: macos-latest + matrix-name: macos + upload-artifact: true + + build-windows: + name: Build Windows + runs-on: windows-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build + uses: ./.github/actions/build + with: + node-version: ${{ env.NODE_VERSION }} + matrix-os: windows-latest + matrix-name: win + upload-artifact: true + + # ARM Linux: + + build-linux-armv7l: + name: Build Linux ARMv7l + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build ARMv7l + uses: ./.github/actions/build-linux-arm + with: + node-version: ${{ env.NODE_VERSION }} + matrix-name: armv7l + matrix-cpu: cortex-a8 + matrix-image: raspios_lite:latest + upload-artifact: true + + build-linux-arm64: + name: Build Linux ARM64 + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Build ARM64 + uses: ./.github/actions/build-linux-arm + with: + node-version: ${{ env.NODE_VERSION }} + matrix-name: arm64 + matrix-cpu: cortex-a53 + matrix-image: raspios_lite_arm64:latest + upload-artifact: true + + ### + + upload-release: + name: Upload and Create Release + needs: + - build-ubuntu + - build-macos + - build-windows + - build-linux-armv7l + - build-linux-arm64 + runs-on: ubuntu-latest + steps: + - name: Download all artifacts + uses: actions/download-artifact@v4 + with: + path: ./artifacts + + - name: List downloaded artifacts + run: ls -R ./artifacts + + - name: Create GitHub Release + uses: softprops/action-gh-release@v2 + with: + name: Release ${{ github.ref_name }} + tag_name: ${{ github.ref }} + files: | + artifacts/**/*.dmg + artifacts/**/*.snap + artifacts/**/*.AppImage + artifacts/**/*.deb + artifacts/**/*.pacman + artifacts/**/*.exe + artifacts/**/*.png + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/package.json b/package.json index fe47d738..53b53682 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "hyper", - "version": "4.0.0-q-canary.6", + "version": "4.0.0-q-canary.8", "repository": "quine-global/hyper", "engines": { "node": "20.11.0"