mirror of
https://github.com/enso-org/enso.git
synced 2024-08-17 00:40:34 +03:00
New GUI/IDE build script support (#7832)
This PR adds support for the new Vue-based GUI (aka `gui2`). The user-facing changes are primarily: * support for `./run gui2` and `./run ide2` commands (that build just the new GUI and the whole IDE package with new GUI embedded — respectively); * the top-level `test` and `lint` commands will now invoke the relevant commands on the new GUI --------- Co-authored-by: Paweł Grabarz <frizi09@gmail.com>
This commit is contained in:
parent
8d8c0b62d6
commit
2d39e644b8
435
.github/workflows/gui.yml
vendored
435
.github/workflows/gui.yml
vendored
@ -24,7 +24,7 @@ jobs:
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.4.0
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
@ -225,7 +225,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run --upload-artifacts ${{ runner.os == 'Linux' }} wasm build
|
||||
- run: ./run wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}
|
||||
env:
|
||||
ENSO_AG_GRID_LICENSE_KEY: ${{ secrets.ENSO_AG_GRID_LICENSE_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -282,7 +282,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run --upload-artifacts ${{ runner.os == 'Linux' }} wasm build
|
||||
- run: ./run wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}
|
||||
env:
|
||||
ENSO_AG_GRID_LICENSE_KEY: ${{ secrets.ENSO_AG_GRID_LICENSE_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -341,7 +341,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run --upload-artifacts ${{ runner.os == 'Linux' }} wasm build
|
||||
- run: ./run wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}
|
||||
env:
|
||||
ENSO_AG_GRID_LICENSE_KEY: ${{ secrets.ENSO_AG_GRID_LICENSE_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@ -483,8 +483,423 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-ide-linux:
|
||||
name: Package IDE (linux)
|
||||
enso-build-ci-gen-job-new-gui-build-linux:
|
||||
name: New (Vue) GUI build (linux)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
- engine
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-build-macos:
|
||||
name: New (Vue) GUI build (macos)
|
||||
runs-on:
|
||||
- macos-latest
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-build-windows:
|
||||
name: New (Vue) GUI build (windows)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Windows
|
||||
- engine
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 build
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-new-gui-test-linux:
|
||||
name: New (Vue) GUI tests (linux)
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
- engine
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run gui2 test
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-linux:
|
||||
name: Package New IDE (linux)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-linux
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Linux
|
||||
- engine
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-macos:
|
||||
name: Package New IDE (macos)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-macos
|
||||
runs-on:
|
||||
- macos-latest
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
env:
|
||||
APPLEID: ${{ secrets.APPLE_NOTARIZATION_USERNAME }}
|
||||
APPLEIDPASS: ${{ secrets.APPLE_NOTARIZATION_PASSWORD }}
|
||||
CSC_IDENTITY_AUTO_DISCOVERY: "true"
|
||||
CSC_KEY_PASSWORD: ${{ secrets.APPLE_CODE_SIGNING_CERT_PASSWORD }}
|
||||
CSC_LINK: ${{ secrets.APPLE_CODE_SIGNING_CERT }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-new-ide-windows:
|
||||
name: Package New IDE (windows)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-windows
|
||||
runs-on:
|
||||
- self-hosted
|
||||
- Windows
|
||||
- engine
|
||||
steps:
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Setup conda (GH runners only)
|
||||
uses: s-weigand/setup-conda@v1.0.6
|
||||
with:
|
||||
update-conda: false
|
||||
conda-channels: anaconda, conda-forge
|
||||
- if: startsWith(runner.name, 'GitHub Actions') || startsWith(runner.name, 'Hosted Agent')
|
||||
name: Installing wasm-pack
|
||||
uses: jetli/wasm-pack-action@v0.3.0
|
||||
with:
|
||||
version: v0.10.2
|
||||
- name: Expose Artifact API and context information.
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: "\n core.exportVariable(\"ACTIONS_RUNTIME_TOKEN\", process.env[\"ACTIONS_RUNTIME_TOKEN\"])\n core.exportVariable(\"ACTIONS_RUNTIME_URL\", process.env[\"ACTIONS_RUNTIME_URL\"])\n core.exportVariable(\"GITHUB_RETENTION_DAYS\", process.env[\"GITHUB_RETENTION_DAYS\"])\n console.log(context)\n "
|
||||
- if: runner.os == 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (Windows)
|
||||
run: '"c:\Program Files\Git\bin\bash.exe" -c "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"'
|
||||
shell: cmd
|
||||
- if: runner.os != 'Windows'
|
||||
name: Workaround for https://github.com/actions/checkout/issues/590 (non-Windows)
|
||||
run: "git checkout -f $(git -c user.name=x -c user.email=x@x commit-tree $(git hash-object -t tree /dev/null) < /dev/null) || :"
|
||||
shell: bash
|
||||
- name: Checking out the repository
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
clean: false
|
||||
submodules: recursive
|
||||
- name: Build Script Setup
|
||||
run: ./run --help
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- if: "contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean before
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run ide2 build --backend-source current-ci-run --gui2-upload-artifact false
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
WIN_CSC_KEY_PASSWORD: ${{ secrets.MICROSOFT_CODE_SIGNING_CERT_PASSWORD }}
|
||||
WIN_CSC_LINK: ${{ secrets.MICROSOFT_CODE_SIGNING_CERT }}
|
||||
- if: failure() && runner.os == 'Windows'
|
||||
name: List files if failed (Windows)
|
||||
run: Get-ChildItem -Force -Recurse
|
||||
- if: failure() && runner.os != 'Windows'
|
||||
name: List files if failed (non-Windows)
|
||||
run: ls -lAR
|
||||
- if: "always() && always() && contains(github.event.pull_request.labels.*.name, 'CI: Clean build required')"
|
||||
name: Clean after
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-old-ide-linux:
|
||||
name: Package Old IDE (linux)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-linux
|
||||
- enso-build-ci-gen-job-build-wasm-linux
|
||||
@ -544,8 +959,8 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-ide-macos:
|
||||
name: Package IDE (macos)
|
||||
enso-build-ci-gen-job-package-old-ide-macos:
|
||||
name: Package Old IDE (macos)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-macos
|
||||
- enso-build-ci-gen-job-build-wasm-linux
|
||||
@ -608,8 +1023,8 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
enso-build-ci-gen-job-package-ide-windows:
|
||||
name: Package IDE (windows)
|
||||
enso-build-ci-gen-job-package-old-ide-windows:
|
||||
name: Package Old IDE (windows)
|
||||
needs:
|
||||
- enso-build-ci-gen-job-build-backend-windows
|
||||
- enso-build-ci-gen-job-build-wasm-linux
|
||||
|
2
.github/workflows/release.yml
vendored
2
.github/workflows/release.yml
vendored
@ -106,7 +106,7 @@ jobs:
|
||||
run: ./run git-clean
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
- run: ./run --upload-artifacts ${{ runner.os == 'Linux' }} wasm build
|
||||
- run: ./run wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}
|
||||
env:
|
||||
ENSO_AG_GRID_LICENSE_KEY: ${{ secrets.ENSO_AG_GRID_LICENSE_KEY }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
7
.gitignore
vendored
7
.gitignore
vendored
@ -91,14 +91,17 @@ bench-report*.xml
|
||||
## Binaries ##
|
||||
##############
|
||||
|
||||
/built-distribution/
|
||||
/enso
|
||||
/project-manager
|
||||
*.exe
|
||||
/enso.exp
|
||||
/enso.lib
|
||||
|
||||
*.dll
|
||||
*.exe
|
||||
*.pdb
|
||||
*.so
|
||||
*.jar
|
||||
/built-distribution/
|
||||
|
||||
|
||||
#########
|
||||
|
@ -40,5 +40,9 @@ ci-build/
|
||||
enso/
|
||||
|
||||
# Popular IDEs
|
||||
.idea
|
||||
.bsp
|
||||
.idea
|
||||
.vscode
|
||||
|
||||
# Stray files generated during build
|
||||
svm_*.md
|
||||
|
9
.vscode/settings.json
vendored
9
.vscode/settings.json
vendored
@ -1,10 +1,15 @@
|
||||
{
|
||||
"rust-analyzer.linkedProjects": ["./app/gui2/rust-ffi/Cargo.toml"],
|
||||
"rust-analyzer.linkedProjects": [
|
||||
"./app/gui2/rust-ffi/Cargo.toml"
|
||||
],
|
||||
"vue.complete.casing.status": false,
|
||||
"vue.complete.casing.props": "camel",
|
||||
"vue.complete.casing.tags": "pascal",
|
||||
"auto-snippets.snippets": [
|
||||
{ "language": "vue", "snippet": "Vue single-file component" }
|
||||
{
|
||||
"language": "vue",
|
||||
"snippet": "Vue single-file component"
|
||||
}
|
||||
],
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"eslint.experimental.useFlatConfig": true,
|
||||
|
@ -9,7 +9,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "run-p typecheck build-only",
|
||||
"build": "npm --workspace enso-authentication run compile && run-p typecheck build-only",
|
||||
"preview": "vite preview",
|
||||
"test:unit": "vitest",
|
||||
"test:e2e": "playwright test",
|
||||
|
@ -97,12 +97,12 @@ export class DistributedModule {
|
||||
}
|
||||
|
||||
insertNewNode(offset: number, content: string, meta: NodeMetadata): ExprId {
|
||||
const range = [offset, offset + content.length]
|
||||
const range = [offset, offset + content.length] as const
|
||||
const newId = random.uuidv4() as ExprId
|
||||
this.transact(() => {
|
||||
this.doc.contents.insert(offset, content + '\n')
|
||||
const start = Y.createRelativePositionFromTypeIndex(this.doc.contents, range[0]!)
|
||||
const end = Y.createRelativePositionFromTypeIndex(this.doc.contents, range[1]!)
|
||||
const start = Y.createRelativePositionFromTypeIndex(this.doc.contents, range[0], -1)
|
||||
const end = Y.createRelativePositionFromTypeIndex(this.doc.contents, range[1])
|
||||
this.doc.idMap.set(newId, encodeRange([start, end]))
|
||||
this.doc.metadata.set(newId, meta)
|
||||
})
|
||||
@ -281,7 +281,7 @@ export class IdMap {
|
||||
// For all remaining expressions, we need to write them into the map.
|
||||
if (!this.accessed.has(expr)) return
|
||||
const range = IdMap.rangeForKey(key)
|
||||
const start = Y.createRelativePositionFromTypeIndex(this.contents, range[0])
|
||||
const start = Y.createRelativePositionFromTypeIndex(this.contents, range[0], -1)
|
||||
const end = Y.createRelativePositionFromTypeIndex(this.contents, range[1])
|
||||
const encoded = encodeRange([start, end])
|
||||
this.yMap.set(expr, encoded)
|
||||
|
@ -5,6 +5,7 @@ const INITIAL_URL_KEY = `Enso-initial-url`
|
||||
import './assets/main.css'
|
||||
|
||||
import { basicSetup } from 'codemirror'
|
||||
import * as dashboard from 'enso-authentication'
|
||||
import { isMac } from 'lib0/environment'
|
||||
import { decodeQueryParams } from 'lib0/url'
|
||||
import { createPinia } from 'pinia'
|
||||
@ -46,8 +47,6 @@ function stopApp() {
|
||||
|
||||
const appRunner = { runApp, stopApp }
|
||||
|
||||
const dashboard = await import('enso-authentication')
|
||||
|
||||
/** The entrypoint into the IDE. */
|
||||
function main() {
|
||||
/** Note: Signing out always redirects to `/`. It is impossible to make this work,
|
||||
|
@ -154,7 +154,7 @@ export const useGraphStore = defineStore('graph', () => {
|
||||
rootSpan: stmt.expression,
|
||||
position: meta == null ? Vec2.Zero() : new Vec2(meta.x, -meta.y),
|
||||
docRange: [
|
||||
Y.createRelativePositionFromTypeIndex(text, stmt.exprOffset),
|
||||
Y.createRelativePositionFromTypeIndex(text, stmt.exprOffset, -1),
|
||||
Y.createRelativePositionFromTypeIndex(text, stmt.exprOffset + stmt.expression.length),
|
||||
],
|
||||
}
|
||||
|
@ -349,16 +349,18 @@ class ModulePersistence extends ObservableV2<{ removed: () => void }> {
|
||||
newContent += synced.code
|
||||
}
|
||||
|
||||
newContent += META_TAG + '\n'
|
||||
|
||||
const metaStartLine = (newContent.match(/\n/g) ?? []).length
|
||||
let metaContent = META_TAG + '\n'
|
||||
|
||||
if (idMapKeys != null || (contentDelta && contentDelta.length > 0)) {
|
||||
if (
|
||||
idMapKeys != null ||
|
||||
synced.idMapJson == null ||
|
||||
(contentDelta && contentDelta.length > 0)
|
||||
) {
|
||||
const idMapJson = json.stringify(idMapToArray(this.doc.idMap))
|
||||
allEdits.push(...applyDiffAsTextEdits(metaStartLine, synced.idMapJson ?? '', idMapJson))
|
||||
newContent += idMapJson + '\n'
|
||||
metaContent += idMapJson + '\n'
|
||||
} else {
|
||||
newContent += synced.idMapJson + '\n'
|
||||
metaContent += (synced.idMapJson ?? '[]') + '\n'
|
||||
}
|
||||
|
||||
const nodeMetadata = this.syncedMeta.ide.node
|
||||
@ -385,14 +387,15 @@ class ModulePersistence extends ObservableV2<{ removed: () => void }> {
|
||||
}
|
||||
|
||||
const metadataJson = json.stringify(this.syncedMeta)
|
||||
allEdits.push(
|
||||
...applyDiffAsTextEdits(metaStartLine + 1, synced.metadataJson ?? '', metadataJson),
|
||||
)
|
||||
newContent += metadataJson
|
||||
metaContent += metadataJson
|
||||
} else {
|
||||
newContent += synced.metadataJson
|
||||
metaContent += synced.metadataJson ?? '{}'
|
||||
}
|
||||
|
||||
const oldMetaContent = this.syncedContent.slice(synced.code.length)
|
||||
allEdits.push(...applyDiffAsTextEdits(metaStartLine, oldMetaContent, metaContent))
|
||||
newContent += metaContent
|
||||
|
||||
const newVersion = computeTextChecksum(newContent)
|
||||
|
||||
if (DEBUG_LOG_SYNC) {
|
||||
|
@ -99,7 +99,7 @@ export function createElectronBuilderConfig(passedArgs: Arguments): electronBuil
|
||||
extraMetadata: {
|
||||
version: BUILD_INFO.version,
|
||||
},
|
||||
copyright: 'Copyright © 2022 ${author}.',
|
||||
copyright: `Copyright © ${new Date().getFullYear()} ${common.COMPANY_NAME}`,
|
||||
artifactName: 'enso-${os}-${version}.${ext}',
|
||||
/** Definitions of URL {@link electronBuilder.Protocol} schemes used by the IDE.
|
||||
*
|
||||
|
@ -100,6 +100,7 @@ export class Server {
|
||||
logger.error(`Error creating server:`, err.http)
|
||||
reject(err)
|
||||
}
|
||||
// Prepare the YDoc server access point for the new Vue-based GUI.
|
||||
if (httpServer) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access,
|
||||
// @typescript-eslint/no-unsafe-call
|
||||
|
@ -18,6 +18,9 @@ export const DEEP_LINK_SCHEME = 'enso'
|
||||
/** Name of the product. */
|
||||
export const PRODUCT_NAME = 'Enso'
|
||||
|
||||
/** Company name, used as the copyright holder. */
|
||||
export const COMPANY_NAME = 'New Byte Order sp. z o.o.'
|
||||
|
||||
/** COOP, COEP, and CORP headers: https://web.dev/coop-coep/
|
||||
*
|
||||
* These are required to increase the resolution of `performance.now()` timers,
|
||||
|
@ -9,6 +9,7 @@
|
||||
"./tailwind.css": "./tailwind.css"
|
||||
},
|
||||
"scripts": {
|
||||
"compile": "tsc",
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
|
6
app/ide-desktop/lib/types/modules.d.ts
vendored
6
app/ide-desktop/lib/types/modules.d.ts
vendored
@ -185,11 +185,7 @@ declare module 'create-servers' {
|
||||
option: CreateServersOptions,
|
||||
// The types come from a third-party API and cannot be changed.
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
handler: (
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
err: HttpError | undefined,
|
||||
servers: CreatedServers
|
||||
) => void
|
||||
handler: (err: HttpError | undefined, servers: CreatedServers) => void
|
||||
): unknown
|
||||
}
|
||||
|
||||
|
@ -6,7 +6,7 @@ required-versions:
|
||||
# NB. The Rust version is pinned in rust-toolchain.toml.
|
||||
# NB. The Node version is pinned in .node-version.
|
||||
cargo-watch: ^8.1.1
|
||||
wasm-pack: ^0.10.2
|
||||
wasm-pack: ^0.12.1
|
||||
# TODO [mwu]: Script can install `flatc` later on (if `conda` is present), so this is not required. However it should
|
||||
# be required, if `conda` is missing.
|
||||
# flatc: =1.12.0
|
||||
|
@ -15,6 +15,8 @@
|
||||
shader-tools.yml:
|
||||
app/:
|
||||
gui/:
|
||||
gui2/: # The new, Vue-based GUI.
|
||||
dist/:
|
||||
ide-desktop/:
|
||||
lib/:
|
||||
client/:
|
||||
@ -57,6 +59,9 @@
|
||||
index.js:
|
||||
style.css:
|
||||
|
||||
gui2/:
|
||||
assets/:
|
||||
|
||||
# Final WASM artifacts in `dist` directory.
|
||||
wasm/:
|
||||
dynamic-assets/: # Assets used by the WASM application.
|
||||
|
@ -445,6 +445,7 @@ pub fn gui() -> Result<Workflow> {
|
||||
workflow.add(PRIMARY_OS, job::Lint);
|
||||
workflow.add(PRIMARY_OS, job::WasmTest);
|
||||
workflow.add(PRIMARY_OS, job::NativeTest);
|
||||
workflow.add(PRIMARY_OS, job::NewGuiTest);
|
||||
|
||||
// FIXME: Integration tests are currently always failing.
|
||||
// The should be reinstated when fixed.
|
||||
@ -461,10 +462,14 @@ pub fn gui() -> Result<Workflow> {
|
||||
let _wasm_job = workflow.add(os, job::BuildWasm);
|
||||
}
|
||||
let project_manager_job = workflow.add(os, job::BuildBackend);
|
||||
workflow.add_customized(os, job::PackageIde, |job| {
|
||||
workflow.add_customized(os, job::PackageOldIde, |job| {
|
||||
job.needs.insert(wasm_job_linux.clone());
|
||||
job.needs.insert(project_manager_job);
|
||||
job.needs.insert(project_manager_job.clone());
|
||||
});
|
||||
workflow.add_customized(os, job::PackageNewIde, |job| {
|
||||
job.needs.insert(project_manager_job.clone());
|
||||
});
|
||||
workflow.add(os, job::NewGuiBuild);
|
||||
}
|
||||
Ok(workflow)
|
||||
}
|
||||
|
@ -105,6 +105,22 @@ impl JobArchetype for NativeTest {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NewGuiTest;
|
||||
impl JobArchetype for NewGuiTest {
|
||||
fn job(&self, os: OS) -> Job {
|
||||
plain_job(&os, "New (Vue) GUI tests", "gui2 test")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct NewGuiBuild;
|
||||
impl JobArchetype for NewGuiBuild {
|
||||
fn job(&self, os: OS) -> Job {
|
||||
plain_job(&os, "New (Vue) GUI build", "gui2 build")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct WasmTest;
|
||||
impl JobArchetype for WasmTest {
|
||||
@ -132,7 +148,7 @@ impl JobArchetype for BuildWasm {
|
||||
plain_job_customized(
|
||||
&os,
|
||||
"Build GUI (WASM)",
|
||||
" --upload-artifacts ${{ runner.os == 'Linux' }} wasm build",
|
||||
"wasm build --wasm-upload-artifact ${{ runner.os == 'Linux' }}",
|
||||
|step| vec![step.with_secret_exposed(crate::env::ENSO_AG_GRID_LICENSE_KEY)],
|
||||
)
|
||||
}
|
||||
@ -222,18 +238,31 @@ pub fn expose_os_specific_signing_secret(os: OS, step: Step) -> Step {
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct PackageIde;
|
||||
impl JobArchetype for PackageIde {
|
||||
pub struct PackageOldIde;
|
||||
impl JobArchetype for PackageOldIde {
|
||||
fn job(&self, os: OS) -> Job {
|
||||
plain_job_customized(
|
||||
&os,
|
||||
"Package IDE",
|
||||
"Package Old IDE",
|
||||
"ide build --wasm-source current-ci-run --backend-source current-ci-run",
|
||||
|step| vec![expose_os_specific_signing_secret(os, step)],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct PackageNewIde;
|
||||
impl JobArchetype for PackageNewIde {
|
||||
fn job(&self, os: OS) -> Job {
|
||||
plain_job_customized(
|
||||
&os,
|
||||
"Package New IDE",
|
||||
"ide2 build --backend-source current-ci-run --gui2-upload-artifact false",
|
||||
|step| vec![expose_os_specific_signing_secret(os, step)],
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
pub struct CiCheckBackend;
|
||||
impl JobArchetype for CiCheckBackend {
|
||||
|
@ -4,6 +4,7 @@ use crate::ide::web::env::CSC_KEY_PASSWORD;
|
||||
use crate::paths::generated;
|
||||
use crate::project::gui::BuildInfo;
|
||||
use crate::project::wasm;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::ProcessWrapper;
|
||||
|
||||
use anyhow::Context;
|
||||
@ -165,9 +166,7 @@ impl<Output: AsRef<Path>> ContentEnvironment<TempDir, Output> {
|
||||
build_info: &BuildInfo,
|
||||
output_path: Output,
|
||||
) -> Result<Self> {
|
||||
// wasm build already does this, running `npm install` twice concurrently leads to broken
|
||||
// builds.
|
||||
// self.npm()?.install().run_ok().await?;
|
||||
crate::web::install(&ide.repo_root).await?;
|
||||
let asset_dir = TempDir::new()?;
|
||||
let assets_download = download_js_assets(&asset_dir);
|
||||
let fonts_download = fonts::install_html_fonts(&ide.cache, &ide.octocrab, &asset_dir);
|
||||
@ -240,11 +239,11 @@ impl FallibleManipulator for ProjectManagerInfo {
|
||||
#[derive(Clone, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct IdeDesktop {
|
||||
pub build_sbt: generated::RepoRootBuildSbt,
|
||||
pub package_dir: generated::RepoRoot,
|
||||
pub build_sbt: generated::RepoRootBuildSbt,
|
||||
pub repo_root: generated::RepoRoot,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub octocrab: Octocrab,
|
||||
pub cache: ide_ci::cache::Cache,
|
||||
pub octocrab: Octocrab,
|
||||
pub cache: ide_ci::cache::Cache,
|
||||
}
|
||||
|
||||
impl IdeDesktop {
|
||||
@ -255,7 +254,7 @@ impl IdeDesktop {
|
||||
) -> Self {
|
||||
Self {
|
||||
build_sbt: repo_root.build_sbt.clone(),
|
||||
package_dir: repo_root.clone(),
|
||||
repo_root: repo_root.clone(),
|
||||
octocrab,
|
||||
cache,
|
||||
}
|
||||
@ -265,13 +264,13 @@ impl IdeDesktop {
|
||||
let mut command = Npm.cmd()?;
|
||||
command.arg("--color").arg("always");
|
||||
command.arg("--yes");
|
||||
command.current_dir(&self.package_dir);
|
||||
command.current_dir(&self.repo_root);
|
||||
command.stdin(Stdio::null()); // nothing in that process subtree should require input
|
||||
Ok(command)
|
||||
}
|
||||
|
||||
pub fn write_build_info(&self, info: &BuildInfo) -> Result {
|
||||
let path = self.package_dir.join(&*BUILD_INFO);
|
||||
let path = self.repo_root.join(&*BUILD_INFO);
|
||||
path.write_as_json(info)
|
||||
}
|
||||
|
||||
@ -340,7 +339,7 @@ impl IdeDesktop {
|
||||
err))]
|
||||
pub async fn dist(
|
||||
&self,
|
||||
gui: &crate::project::gui::Artifact,
|
||||
gui: &impl IsArtifact,
|
||||
project_manager: &crate::project::backend::Artifact,
|
||||
output_path: impl AsRef<Path>,
|
||||
target_os: OS,
|
||||
@ -354,11 +353,12 @@ impl IdeDesktop {
|
||||
graalvm.install_if_missing(&self.cache).await?;
|
||||
}
|
||||
|
||||
self.npm()?.install().run_ok().await?;
|
||||
|
||||
crate::web::install(&self.repo_root).await?;
|
||||
let pm_bundle = ProjectManagerInfo::new(project_manager)?;
|
||||
let client_build = self
|
||||
.npm()?
|
||||
.set_env(env::ENSO_BUILD_GUI, gui.as_path())?
|
||||
.set_env(env::ENSO_BUILD_GUI, gui.as_ref())?
|
||||
.set_env(env::ENSO_BUILD_IDE, output_path.as_ref())?
|
||||
.try_applying(&pm_bundle)?
|
||||
.workspace(Workspaces::Enso)
|
||||
@ -389,7 +389,7 @@ impl IdeDesktop {
|
||||
self.npm()?
|
||||
.try_applying(&icons)?
|
||||
// .env("DEBUG", "electron-builder")
|
||||
.set_env(env::ENSO_BUILD_GUI, gui.as_path())?
|
||||
.set_env(env::ENSO_BUILD_GUI, gui.as_ref())?
|
||||
.set_env(env::ENSO_BUILD_IDE, output_path.as_ref())?
|
||||
.set_env(env::ENSO_BUILD_PROJECT_MANAGER, project_manager.as_ref())?
|
||||
.set_env_opt(env::PYTHON_PATH, python_path.as_ref())?
|
||||
@ -416,7 +416,7 @@ impl IdeDesktop {
|
||||
get_project_manager: BoxFuture<'static, Result<crate::project::backend::Artifact>>,
|
||||
ide_options: Vec<String>,
|
||||
) -> Result {
|
||||
let npm_install_job = self.npm()?.install().run_ok();
|
||||
let npm_install_job = crate::web::install(&self.repo_root);
|
||||
// TODO: This could be possibly optimized by awaiting WASM a bit later, and passing its
|
||||
// future to the ContentEnvironment. However, the code would get a little tricky.
|
||||
// Should be reconsidered in the future, based on actual timings.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#![feature(once_cell)]
|
||||
#![feature(duration_constants)]
|
||||
#![feature(slice_take)]
|
||||
#![feature(future_join)]
|
||||
// === Standard Linter Configuration ===
|
||||
#![deny(non_ascii_idents)]
|
||||
#![warn(unsafe_code)]
|
||||
@ -66,6 +67,7 @@ pub mod repo;
|
||||
pub mod rust;
|
||||
pub mod source;
|
||||
pub mod version;
|
||||
pub mod web;
|
||||
|
||||
/// Get version of Enso from the `build.sbt` file contents.
|
||||
pub fn get_enso_version(build_sbt_contents: &str) -> Result<Version> {
|
||||
|
@ -27,7 +27,9 @@ use octocrab::models::repos::Asset;
|
||||
pub mod backend;
|
||||
pub mod engine;
|
||||
pub mod gui;
|
||||
pub mod gui2;
|
||||
pub mod ide;
|
||||
pub mod ide2;
|
||||
pub mod project_manager;
|
||||
pub mod runtime;
|
||||
pub mod wasm;
|
||||
@ -48,7 +50,7 @@ pub fn path_to_extract() -> Option<PathBuf> {
|
||||
/// A built target, contained under a single directory.
|
||||
///
|
||||
/// The `AsRef<Path>` trait must return that directory path.
|
||||
pub trait IsArtifact: Clone + AsRef<Path> + Sized + Send + Sync + 'static {}
|
||||
pub trait IsArtifact: Clone + AsRef<Path> + Debug + Sized + Send + Sync + 'static {}
|
||||
|
||||
/// Plain artifact is just a folder with... things.
|
||||
#[derive(Clone, Derivative)]
|
||||
@ -89,9 +91,6 @@ pub struct Context {
|
||||
/// Stores things like downloaded release assets to save time.
|
||||
pub cache: Cache,
|
||||
|
||||
/// Whether built artifacts should be uploaded as part of CI run. Works only in CI environment.
|
||||
pub upload_artifacts: bool,
|
||||
|
||||
/// Directory being an `enso` repository's working copy.
|
||||
///
|
||||
/// The directory is not required to be a git repository. It is allowed to use source tarballs
|
||||
@ -126,6 +125,7 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
/// Create a full artifact description from an on-disk representation.
|
||||
fn adapt_artifact(self, path: impl AsRef<Path>) -> BoxFuture<'static, Result<Self::Artifact>>;
|
||||
|
||||
/// Produce the target artifacts, according to the job description.
|
||||
fn get(
|
||||
&self,
|
||||
context: Context,
|
||||
@ -133,10 +133,10 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let GetTargetJob { destination, inner } = job;
|
||||
match inner {
|
||||
Source::BuildLocally(inputs) =>
|
||||
self.build(context, WithDestination { inner: inputs, destination }),
|
||||
Source::BuildLocally(local_build) =>
|
||||
self.build(context, WithDestination::new(local_build, destination)),
|
||||
Source::External(external) =>
|
||||
self.get_external(context, WithDestination { inner: external, destination }),
|
||||
self.get_external(context, WithDestination::new(external, destination)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -178,8 +178,8 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
job: BuildTargetJob<Self>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let span = debug_span!("Building.", ?self, ?context, ?job).entered();
|
||||
let upload_artifacts = context.upload_artifacts;
|
||||
let artifact_fut = self.build_internal(context, job);
|
||||
let upload_artifacts = job.should_upload_artifact;
|
||||
let artifact_fut = self.build_internal(context, job.map(|job| job.input));
|
||||
let this = self.clone();
|
||||
async move {
|
||||
let artifact = artifact_fut.await.context(format!("Failed to build {this:?}."))?;
|
||||
@ -208,7 +208,7 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: BuildTargetJob<Self>,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>>;
|
||||
|
||||
/// Upload artifact to the current GitHub Actions run.
|
||||
@ -226,7 +226,7 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
ci_run: CiRunSource,
|
||||
output_path: impl AsRef<Path> + Send + Sync + 'static,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let Context { octocrab, cache, upload_artifacts: _, repo_root: _ } = context;
|
||||
let Context { octocrab, cache, repo_root: _ } = context;
|
||||
let CiRunSource { run_id, artifact_name, repository } = ci_run;
|
||||
let repository = repository.handle(&octocrab);
|
||||
let span = info_span!("Downloading CI Artifact.", %artifact_name, %repository, target = output_path.as_ref().as_str());
|
||||
@ -285,7 +285,7 @@ pub trait IsTarget: Clone + Debug + Sized + Send + Sync + 'static {
|
||||
source: ReleaseSource,
|
||||
destination: PathBuf,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let Context { octocrab, cache, upload_artifacts: _, repo_root: _ } = context;
|
||||
let Context { octocrab, cache, repo_root: _ } = context;
|
||||
let span = info_span!("Downloading built target from a release asset.",
|
||||
asset_id = source.asset_id.0,
|
||||
repo = %source.repository);
|
||||
@ -403,19 +403,17 @@ pub fn perhaps_watch<T: IsWatchable>(
|
||||
job: GetTargetJob<T>,
|
||||
watch_input: T::WatchInput,
|
||||
) -> BoxFuture<'static, Result<PerhapsWatched<T>>> {
|
||||
match job.inner {
|
||||
let WithDestination { inner, destination } = job;
|
||||
match inner {
|
||||
Source::BuildLocally(local) => target
|
||||
.watch(context, WatchTargetJob {
|
||||
watch_input,
|
||||
build: WithDestination { inner: local, destination: job.destination },
|
||||
build: WithDestination::new(local, destination),
|
||||
})
|
||||
.map_ok(PerhapsWatched::Watched)
|
||||
.boxed(),
|
||||
Source::External(external) => target
|
||||
.get_external(context, WithDestination {
|
||||
inner: external,
|
||||
destination: job.destination,
|
||||
})
|
||||
.get_external(context, WithDestination { inner: external, destination })
|
||||
.map_ok(PerhapsWatched::Static)
|
||||
.boxed(),
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ use crate::paths::TargetTriple;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::source::BuildTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
use crate::version::Versions;
|
||||
|
||||
@ -147,7 +146,7 @@ impl IsTarget for Backend {
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: BuildTargetJob<Self>,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let WithDestination { inner, destination } = job;
|
||||
let target_os = self.target_os;
|
||||
|
@ -9,7 +9,7 @@ use crate::project::IsWatchable;
|
||||
use crate::project::IsWatcher;
|
||||
use crate::project::PerhapsWatched;
|
||||
use crate::project::Wasm;
|
||||
use crate::source::BuildTargetJob;
|
||||
use crate::source::BuildSource;
|
||||
use crate::source::GetTargetJob;
|
||||
use crate::source::WatchTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
@ -120,7 +120,7 @@ impl IsTarget for Gui {
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: BuildTargetJob<Self>,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let WithDestination { inner, destination } = job;
|
||||
async move {
|
||||
@ -134,7 +134,7 @@ impl IsTarget for Gui {
|
||||
}
|
||||
|
||||
let ide = ide_desktop_from_context(&context);
|
||||
ide.npm()?.install().run_ok().await?;
|
||||
crate::web::install(&ide.repo_root).await?;
|
||||
|
||||
let wasm = Wasm.get(context, inner.wasm);
|
||||
ide.build_content(wasm, &inner.build_info.await?, &destination).await?;
|
||||
@ -169,8 +169,12 @@ impl IsWatchable for Gui {
|
||||
context: Context,
|
||||
job: WatchTargetJob<Self>,
|
||||
) -> BoxFuture<'static, Result<Self::Watcher>> {
|
||||
let WatchTargetJob { watch_input, build: WithDestination { inner, destination } } = job;
|
||||
let BuildInput { build_info, wasm } = inner;
|
||||
let WatchTargetJob {
|
||||
watch_input,
|
||||
build:
|
||||
WithDestination { inner: BuildSource { input, should_upload_artifact: _ }, destination },
|
||||
} = job;
|
||||
let BuildInput { build_info, wasm } = input;
|
||||
let perhaps_watched_wasm = perhaps_watch(Wasm, context.clone(), wasm, watch_input.wasm);
|
||||
let ide = ide_desktop_from_context(&context);
|
||||
async move {
|
||||
@ -194,8 +198,12 @@ impl Gui {
|
||||
context: Context,
|
||||
job: WatchTargetJob<Self>,
|
||||
) -> GuiBuildWithWatchedWasm {
|
||||
let WatchTargetJob { watch_input, build: WithDestination { inner, destination } } = job;
|
||||
let BuildInput { build_info, wasm } = inner;
|
||||
let WatchTargetJob {
|
||||
watch_input,
|
||||
build:
|
||||
WithDestination { inner: BuildSource { input, should_upload_artifact: _ }, destination },
|
||||
} = job;
|
||||
let BuildInput { build_info, wasm } = input;
|
||||
let WatchInput { wasm: wasm_watch_input } = watch_input;
|
||||
let perhaps_watched_wasm = perhaps_watch(Wasm, context, wasm, wasm_watch_input);
|
||||
GuiBuildWithWatchedWasm { perhaps_watched_wasm, build_info, destination }
|
||||
|
139
build/build/src/project/gui2.rs
Normal file
139
build/build/src/project/gui2.rs
Normal file
@ -0,0 +1,139 @@
|
||||
//! Build logic for the "new GUI" (gui2) project.
|
||||
//!
|
||||
//! The new GUI is Vue.js-based and located under `app/gui2`.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::paths::generated::RepoRootAppGui2Dist;
|
||||
use crate::paths::generated::RepoRootDistGui2Assets;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::source::WithDestination;
|
||||
|
||||
use ide_ci::ok_ready_boxed;
|
||||
use ide_ci::programs::node::NpmCommand;
|
||||
use ide_ci::programs::Npm;
|
||||
|
||||
|
||||
|
||||
// ===============
|
||||
// === Scripts ===
|
||||
// ===============
|
||||
|
||||
/// The scripts defined in `package.json`.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Scripts {
|
||||
Dev,
|
||||
Build,
|
||||
Preview,
|
||||
#[strum(serialize = "test:unit")]
|
||||
TestUnit,
|
||||
#[strum(serialize = "test:e2e")]
|
||||
TestE2e,
|
||||
BuildOnly,
|
||||
TypeCheck,
|
||||
Lint,
|
||||
Format,
|
||||
BuildRustFfi,
|
||||
}
|
||||
|
||||
pub fn script(repo_root: impl AsRef<Path>, script: Scripts) -> Result<NpmCommand> {
|
||||
let mut ret = Npm.cmd()?;
|
||||
ret.current_dir(repo_root).workspace(crate::web::Workspace::EnsoGui2).run(script.as_ref());
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Commands ===
|
||||
// ================
|
||||
|
||||
/// Run steps that should be done along with the "lint"
|
||||
pub fn lint(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
script(&repo_root, Scripts::Lint)?.run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
/// Run unit tests.
|
||||
pub fn unit_tests(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
let repo_root = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
crate::web::install(&repo_root).await?;
|
||||
script(&repo_root, Scripts::TestUnit)?.arg("run").run_ok().await
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ================
|
||||
// === Artifact ===
|
||||
// ================
|
||||
|
||||
/// The [artifact](IsArtifact) for the new GUI.
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Deref)]
|
||||
pub struct Artifact(pub RepoRootAppGui2Dist);
|
||||
|
||||
impl AsRef<Path> for Artifact {
|
||||
fn as_ref(&self) -> &Path {
|
||||
self.0.as_path()
|
||||
}
|
||||
}
|
||||
|
||||
impl IsArtifact for Artifact {}
|
||||
|
||||
impl Artifact {
|
||||
pub fn new(path: impl AsRef<Path>) -> Self {
|
||||
Artifact(RepoRootAppGui2Dist::new_root(path.as_ref()))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ==============
|
||||
// === Target ===
|
||||
// ==============
|
||||
|
||||
/// The [target](IsTarget) for the new GUI.
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
|
||||
pub struct Gui2;
|
||||
|
||||
impl IsTarget for Gui2 {
|
||||
type BuildInput = ();
|
||||
type Artifact = Artifact;
|
||||
|
||||
fn artifact_name(&self) -> String {
|
||||
"gui2".to_owned()
|
||||
}
|
||||
|
||||
fn adapt_artifact(self, path: impl AsRef<Path>) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
ok_ready_boxed(Artifact::new(path))
|
||||
}
|
||||
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let WithDestination { inner: _, destination } = job;
|
||||
async move {
|
||||
let repo_root = &context.repo_root;
|
||||
crate::web::install(repo_root).await?;
|
||||
script(repo_root, Scripts::Build)?.run_ok().await?;
|
||||
ide_ci::fs::mirror_directory(
|
||||
&repo_root.app.gui_2.dist,
|
||||
&destination.join(RepoRootDistGui2Assets::segment_name()),
|
||||
)
|
||||
.await?;
|
||||
Ok(Artifact::new(destination))
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ use crate::project::gui::ide_desktop_from_context;
|
||||
use crate::project::gui::GuiBuildWithWatchedWasm;
|
||||
use crate::project::Context;
|
||||
use crate::project::Gui;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::source::WatchTargetJob;
|
||||
|
||||
use ide_ci::actions::artifacts::upload_compressed_directory;
|
||||
@ -25,7 +26,7 @@ pub struct Artifact {
|
||||
}
|
||||
|
||||
impl Artifact {
|
||||
fn new(
|
||||
pub fn new(
|
||||
target_os: OS,
|
||||
target_arch: Arch,
|
||||
version: &Version,
|
||||
@ -60,12 +61,14 @@ impl Artifact {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn upload_as_ci_artifact(&self) -> Result {
|
||||
pub async fn upload_as_ci_artifact(&self, prefix: impl AsRef<str>) -> Result {
|
||||
if is_in_env() {
|
||||
upload_compressed_directory(&self.unpacked, format!("ide-unpacked-{TARGET_OS}"))
|
||||
let prefix = prefix.as_ref();
|
||||
upload_compressed_directory(&self.unpacked, format!("{prefix}-unpacked-{TARGET_OS}"))
|
||||
.await?;
|
||||
upload_single_file(&self.image, format!("ide-{TARGET_OS}")).await?;
|
||||
upload_single_file(&self.image_checksum, format!("ide-{TARGET_OS}")).await?;
|
||||
let packed_artifact_name = format!("{prefix}-{TARGET_OS}");
|
||||
upload_single_file(&self.image, &packed_artifact_name).await?;
|
||||
upload_single_file(&self.image_checksum, &packed_artifact_name).await?;
|
||||
} else {
|
||||
info!("Not in the CI environment, will not upload the artifacts.")
|
||||
}
|
||||
@ -91,14 +94,16 @@ impl Artifact {
|
||||
|
||||
#[derive(derivative::Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildInput {
|
||||
pub struct BuildInput<GuiArtifact> {
|
||||
#[derivative(Debug(format_with = "std::fmt::Display::fmt"))]
|
||||
pub version: Version,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub project_manager: BoxFuture<'static, Result<crate::project::backend::Artifact>>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
pub gui: BoxFuture<'static, Result<crate::project::gui::Artifact>>,
|
||||
pub gui: BoxFuture<'static, Result<GuiArtifact>>,
|
||||
pub electron_target: Option<String>,
|
||||
/// The name base used to generate CI run artifact names.
|
||||
pub artifact_name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
@ -117,10 +122,10 @@ impl Ide {
|
||||
pub fn build(
|
||||
&self,
|
||||
context: &Context,
|
||||
input: BuildInput,
|
||||
input: BuildInput<impl IsArtifact>,
|
||||
output_path: impl AsRef<Path> + Send + Sync + 'static,
|
||||
) -> BoxFuture<'static, Result<Artifact>> {
|
||||
let BuildInput { version, project_manager, gui, electron_target } = input;
|
||||
let BuildInput { version, project_manager, gui, electron_target, artifact_name: _ } = input;
|
||||
let ide_desktop = ide_desktop_from_context(context);
|
||||
let target_os = self.target_os;
|
||||
let target_arch = self.target_arch;
|
||||
@ -155,30 +160,3 @@ impl Ide {
|
||||
.boxed()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// impl IsTarget for Ide {
|
||||
// type BuildInput = BuildInput;
|
||||
// type Output = Artifact;
|
||||
//
|
||||
// fn artifact_name(&self) -> &str {
|
||||
// // Version is not part of the name intentionally. We want to refer to PM bundles as
|
||||
// // artifacts without knowing their version.
|
||||
// static NAME: LazyLock<String> = LazyLock::new(|| format!("gui-{}", TARGET_OS));
|
||||
// &*NAME
|
||||
// }
|
||||
//
|
||||
// fn build(
|
||||
// &self,
|
||||
// input: Self::BuildInput,
|
||||
// output_path: impl AsRef<Path> + Send + Sync + 'static,
|
||||
// ) -> BoxFuture<'static, Result<Self::Output>> {
|
||||
// let ide_desktop = crate::ide::web::IdeDesktop::new(&input.repo_root.app.ide_desktop);
|
||||
// async move {
|
||||
// let (gui, project_manager) = try_join(input.gui, input.project_manager).await?;
|
||||
// ide_desktop.dist(&gui, &project_manager, &output_path).await?;
|
||||
// Ok(Artifact::new(&input.version, output_path.as_ref()))
|
||||
// }
|
||||
// .boxed()
|
||||
// }
|
||||
// }
|
||||
|
9
build/build/src/project/ide2.rs
Normal file
9
build/build/src/project/ide2.rs
Normal file
@ -0,0 +1,9 @@
|
||||
#[allow(unused_imports)]
|
||||
use crate::prelude::*;
|
||||
|
||||
|
||||
// ==============
|
||||
// === Export ===
|
||||
// ==============
|
||||
|
||||
pub use crate::project::ide::Artifact;
|
@ -9,7 +9,6 @@ use crate::paths::TargetTriple;
|
||||
use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::source::BuildTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
use crate::version::Versions;
|
||||
|
||||
@ -42,7 +41,7 @@ impl IsTarget for Runtime {
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: BuildTargetJob<Self>,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let config = BuildConfigurationFlags {
|
||||
build_engine_package: true,
|
||||
|
@ -7,7 +7,7 @@ use crate::project::Context;
|
||||
use crate::project::IsArtifact;
|
||||
use crate::project::IsTarget;
|
||||
use crate::project::IsWatchable;
|
||||
use crate::source::BuildTargetJob;
|
||||
use crate::source::BuildSource;
|
||||
use crate::source::WatchTargetJob;
|
||||
use crate::source::WithDestination;
|
||||
|
||||
@ -205,9 +205,9 @@ impl IsTarget for Wasm {
|
||||
fn build_internal(
|
||||
&self,
|
||||
context: Context,
|
||||
job: BuildTargetJob<Self>,
|
||||
job: WithDestination<Self::BuildInput>,
|
||||
) -> BoxFuture<'static, Result<Self::Artifact>> {
|
||||
let Context { octocrab: _, cache, upload_artifacts: _, repo_root } = context;
|
||||
let Context { octocrab: _, cache, repo_root } = context;
|
||||
let WithDestination { inner, destination } = job;
|
||||
let span = info_span!("Building WASM.",
|
||||
repo = %repo_root.display(),
|
||||
@ -249,6 +249,7 @@ impl IsTarget for Wasm {
|
||||
info!("Building wasm.");
|
||||
let temp_dir = tempdir()?;
|
||||
let temp_dist = RepoRootDistWasm::new_root(temp_dir.path());
|
||||
crate::web::install(&repo_root).await?;
|
||||
ensogl_pack::build(
|
||||
ensogl_pack::WasmPackOutputs {
|
||||
out_dir: temp_dist.path.clone(),
|
||||
@ -327,11 +328,21 @@ impl IsWatchable for Wasm {
|
||||
.instrument(debug_span!("Initial single build of WASM before setting up cargo-watch."));
|
||||
|
||||
async move {
|
||||
let first_build_output = first_build_job.await?;
|
||||
// Make sure that `npm install` was run, so we can spawned process to skip it.
|
||||
// This prevents issues with multiple `npm install` invocations running in parallel.
|
||||
let npm_install = crate::web::install(&context.repo_root);
|
||||
let (first_build_output, npm_install) =
|
||||
futures::future::join(first_build_job, npm_install).await;
|
||||
npm_install?;
|
||||
let first_build_output = first_build_output?;
|
||||
|
||||
let WatchTargetJob {
|
||||
watch_input: WatchInput { cargo_watch_options: cargo_watch_flags },
|
||||
build: WithDestination { inner, destination },
|
||||
build:
|
||||
WithDestination {
|
||||
inner: BuildSource { input, should_upload_artifact: _ },
|
||||
destination,
|
||||
},
|
||||
} = job;
|
||||
let BuildInput {
|
||||
crate_path,
|
||||
@ -344,7 +355,7 @@ impl IsWatchable for Wasm {
|
||||
uncollapsed_log_level,
|
||||
wasm_size_limit,
|
||||
system_shader_tools: _,
|
||||
} = inner;
|
||||
} = input;
|
||||
|
||||
|
||||
let current_exe = std::env::current_exe()?;
|
||||
@ -379,8 +390,8 @@ impl IsWatchable for Wasm {
|
||||
.arg(current_exe)
|
||||
.arg("--skip-version-check") // We already checked in the parent process.
|
||||
.args(["--cache-path", context.cache.path().as_str()])
|
||||
.args(["--upload-artifacts", context.upload_artifacts.to_string().as_str()])
|
||||
.args(["--repo-path", context.repo_root.as_str()]);
|
||||
.args(["--repo-path", context.repo_root.as_str()])
|
||||
.args(["--skip-npm-install", "false"]);
|
||||
|
||||
// === Build Script command and its options ===
|
||||
watch_cmd
|
||||
|
@ -10,6 +10,7 @@ use octocrab::models::RunId;
|
||||
|
||||
|
||||
|
||||
/// Denotes an external source from which a target artifact can be obtained.
|
||||
#[derive(Clone, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub enum ExternalSource {
|
||||
@ -29,11 +30,23 @@ impl ExternalSource {
|
||||
}
|
||||
}
|
||||
|
||||
/// Describes how to build a target and whether to upload the resulting artifact.
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct BuildSource<Target: IsTarget> {
|
||||
/// Data needed to build the target.
|
||||
pub input: Target::BuildInput,
|
||||
/// Whether to upload the resulting artifact as CI artifact.
|
||||
pub should_upload_artifact: bool,
|
||||
}
|
||||
|
||||
/// Describes how to get a target.
|
||||
#[derive(Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub enum Source<Target: IsTarget> {
|
||||
/// Build the target locally from the sources.
|
||||
#[derivative(Debug = "transparent")]
|
||||
BuildLocally(Target::BuildInput),
|
||||
BuildLocally(BuildSource<Target>),
|
||||
/// Download the target from an external source.
|
||||
#[derivative(Debug = "transparent")]
|
||||
External(ExternalSource),
|
||||
}
|
||||
@ -83,6 +96,10 @@ impl<T: IsTarget> WithDestination<Source<T>> {
|
||||
}
|
||||
|
||||
impl<T> WithDestination<T> {
|
||||
pub fn new(inner: T, destination: impl Into<PathBuf>) -> Self {
|
||||
Self { inner, destination: destination.into() }
|
||||
}
|
||||
|
||||
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> WithDestination<U> {
|
||||
WithDestination { inner: f(self.inner), destination: self.destination }
|
||||
}
|
||||
@ -90,7 +107,7 @@ impl<T> WithDestination<T> {
|
||||
|
||||
pub type GetTargetJob<Target> = WithDestination<Source<Target>>;
|
||||
pub type FetchTargetJob = WithDestination<ExternalSource>;
|
||||
pub type BuildTargetJob<Target> = WithDestination<<Target as IsTarget>::BuildInput>;
|
||||
pub type BuildTargetJob<Target> = WithDestination<BuildSource<Target>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct WatchTargetJob<Target: IsWatchable> {
|
||||
|
87
build/build/src/web.rs
Normal file
87
build/build/src/web.rs
Normal file
@ -0,0 +1,87 @@
|
||||
//! Module for managing the web parts of our codebase.
|
||||
//! This refers to JS/TS components, such as the Vue.js-based GUI, as well as the Electron client
|
||||
//! application.
|
||||
|
||||
use crate::prelude::*;
|
||||
|
||||
use ide_ci::programs::Npm;
|
||||
|
||||
|
||||
|
||||
/// Result of root-level `npm install` call. Should not be accessed directly.
|
||||
static ONCE_INSTALL: tokio::sync::OnceCell<Result> = tokio::sync::OnceCell::const_new();
|
||||
|
||||
/// This method invokes `npm install` in the root repository.
|
||||
///
|
||||
/// It ensures that at most one such invocation is running at any given time.
|
||||
/// If an invocation is already running, it waits for it to finish and then
|
||||
/// shares its result.
|
||||
///
|
||||
/// This method relies on the internal global state. It must not be called multiple times
|
||||
/// with different `repo_root` arguments.
|
||||
///
|
||||
/// It is useful, because otherwise the build script might end up invoking `npm install` multiple
|
||||
/// times, sometimes even in parallel. Unfortunately, in such cases, `npm` might fail with errors.
|
||||
pub fn install(repo_root: impl AsRef<Path>) -> BoxFuture<'static, Result> {
|
||||
let root_path = repo_root.as_ref().to_owned();
|
||||
async move {
|
||||
let ret = ONCE_INSTALL
|
||||
.get_or_init(async || Npm.cmd()?.with_current_dir(&root_path).install().run_ok().await)
|
||||
.await;
|
||||
ret.as_ref().copied().map_err(|e| anyhow!("Failed to install NPM dependencies: {e}"))
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
/// Mark the root repository's NPM as installed.
|
||||
///
|
||||
/// If invoked before `install`, any subsequent `install` call will return `Ok`.
|
||||
/// If it was already installed and failed, the failure will still be returned.
|
||||
pub fn assume_installed() {
|
||||
let _ = ONCE_INSTALL.set(Ok(())).inspect_err(|e| {
|
||||
warn!("Failed to mark NPM as installed, due to an error during a previous run: {e}");
|
||||
});
|
||||
}
|
||||
|
||||
/// The scripts that can be invoked in the root repository's NPM.
|
||||
///
|
||||
/// The list should be kept in sync with the `scripts` section of the root repository's
|
||||
/// `package.json`.
|
||||
#[allow(missing_docs)]
|
||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Script {
|
||||
Format,
|
||||
Prettier,
|
||||
Lint,
|
||||
Test,
|
||||
Typecheck,
|
||||
CiCheck,
|
||||
}
|
||||
|
||||
/// Invoke the given script in the context of the root repository's NPM.
|
||||
pub fn run_script(repo_root: impl AsRef<Path>, script: Script) -> BoxFuture<'static, Result> {
|
||||
let root_path = repo_root.as_ref().to_owned();
|
||||
async move { Npm.cmd()?.with_current_dir(&root_path).run(script.as_ref()).run_ok().await }
|
||||
.boxed()
|
||||
}
|
||||
|
||||
/// The list of NPM workspaces that are part of the root repository.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, strum::AsRefStr)]
|
||||
#[strum(serialize_all = "kebab-case")]
|
||||
pub enum Workspace {
|
||||
EnsoIdeDesktop,
|
||||
Enso,
|
||||
EnsoContent,
|
||||
EnsoDashboard,
|
||||
EnsoIcons,
|
||||
EnsoAuthentication,
|
||||
EnsoGui2,
|
||||
EnsoglRunner,
|
||||
}
|
||||
|
||||
impl AsRef<OsStr> for Workspace {
|
||||
fn as_ref(&self) -> &OsStr {
|
||||
AsRef::<str>::as_ref(self).as_ref()
|
||||
}
|
||||
}
|
@ -19,6 +19,8 @@ pub mod prelude {
|
||||
|
||||
/// Generate the comment that is at the top of each generated workflow file.
|
||||
fn preamble(source: &str) -> String {
|
||||
// To make output consistent across platforms.
|
||||
let source = source.replace('\\', "/");
|
||||
format!(
|
||||
"# This file is auto-generated. Do not edit it manually!\n\
|
||||
# Edit the {source} module instead and run `cargo run --package {}`.",
|
||||
|
@ -246,12 +246,21 @@ pub trait IsCommandWrapper {
|
||||
|
||||
|
||||
|
||||
/// Value-based variant of [`Self::current_dir`], for convenience.
|
||||
fn with_current_dir(self, dir: impl AsRef<Path>) -> Self
|
||||
where Self: Sized {
|
||||
let mut this = self;
|
||||
this.current_dir(dir);
|
||||
this
|
||||
}
|
||||
|
||||
/// Value-based variant of [`Self::with_stdin`], for convenience.
|
||||
fn with_stdin(self, stdin: Stdio) -> Self
|
||||
where Self: Sized {
|
||||
let mut this = self;
|
||||
this.stdin(stdin);
|
||||
this
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: BorrowMut<tokio::process::Command>> IsCommandWrapper for T {
|
||||
|
@ -20,7 +20,9 @@ pub mod backend;
|
||||
pub mod engine;
|
||||
pub mod git_clean;
|
||||
pub mod gui;
|
||||
pub mod gui2;
|
||||
pub mod ide;
|
||||
pub mod ide2;
|
||||
pub mod java_gen;
|
||||
pub mod project_manager;
|
||||
pub mod release;
|
||||
@ -75,10 +77,10 @@ pub trait IsTargetSource {
|
||||
const SOURCE_NAME: &'static str;
|
||||
const PATH_NAME: &'static str;
|
||||
const OUTPUT_PATH_NAME: &'static str;
|
||||
// const UPLOAD_ASSET_NAME: &'static str;
|
||||
const RUN_ID_NAME: &'static str;
|
||||
const RELEASE_DESIGNATOR_NAME: &'static str;
|
||||
const ARTIFACT_NAME_NAME: &'static str;
|
||||
const UPLOAD_ARTIFACT_NAME: &'static str;
|
||||
const DEFAULT_OUTPUT_PATH: &'static str;
|
||||
|
||||
type BuildInput: Clone + Debug + PartialEq + Args + Send + Sync;
|
||||
@ -99,6 +101,7 @@ macro_rules! source_args_hlp {
|
||||
const RUN_ID_NAME: &'static str = concat!($prefix, "-", "run-id");
|
||||
const RELEASE_DESIGNATOR_NAME: &'static str = concat!($prefix, "-", "release");
|
||||
const ARTIFACT_NAME_NAME: &'static str = concat!($prefix, "-", "artifact-name");
|
||||
const UPLOAD_ARTIFACT_NAME: &'static str = concat!($prefix, "-", "upload-artifact");
|
||||
const DEFAULT_OUTPUT_PATH: &'static str = concat!("dist/", $prefix);
|
||||
|
||||
type BuildInput = $inputs;
|
||||
@ -111,8 +114,10 @@ macro_rules! source_args_hlp {
|
||||
pub enum Target {
|
||||
/// Build/Test the Rust part of the GUI.
|
||||
Wasm(wasm::Target),
|
||||
/// Build/Run GUI that consists of WASM and JS parts. This is what we deploy to cloud.
|
||||
/// Build/Run the legacy Rust-based GUI that consists of WASM and JS parts.
|
||||
Gui(gui::Target),
|
||||
/// Build/Run the new, Vue-based GUI.
|
||||
Gui2(gui2::Target),
|
||||
/// Enso Engine Runtime.
|
||||
Runtime(runtime::Target),
|
||||
// /// Project Manager package (just the binary, no Engine)
|
||||
@ -121,8 +126,10 @@ pub enum Target {
|
||||
// Engine(engine::Target),
|
||||
/// Build/Get Project Manager bundle (includes Enso Engine with GraalVM Runtime).
|
||||
Backend(backend::Target),
|
||||
/// Build/Run/Test IDE bundle (includes GUI and Project Manager).
|
||||
/// Build/Run/Test IDE bundle (includes Rust-based GUI and Project Manager).
|
||||
Ide(ide::Target),
|
||||
/// Build/Run/Test IDE bundle (includes Vue-based GUI and Project Manager).
|
||||
Ide2(ide2::Target),
|
||||
/// Clean the repository. Keeps the IntelliJ's .idea directory intact. WARNING: This removes
|
||||
/// files that are not under version control in the repository subtree.
|
||||
GitClean(git_clean::Options),
|
||||
@ -167,10 +174,9 @@ pub struct Cli {
|
||||
#[clap(long, global = true, enso_env())]
|
||||
pub skip_version_check: bool,
|
||||
|
||||
/// Whether built artifacts should be uploaded as part of CI run. Ignored in non-CI
|
||||
/// environment.
|
||||
#[clap(long, global = true, hide = !ide_ci::actions::workflow::is_in_env(), parse(try_from_str), default_value_t = true, enso_env())]
|
||||
pub upload_artifacts: bool,
|
||||
/// Assume that `npm install` was already run in the repository root and skip it.
|
||||
#[clap(long, global = true, enso_env())]
|
||||
pub skip_npm_install: bool,
|
||||
|
||||
#[clap(subcommand)]
|
||||
pub target: Target,
|
||||
@ -214,13 +220,10 @@ pub struct Source<Target: IsTargetSource> {
|
||||
|
||||
/// Used when `SourceKind::Build` is used.
|
||||
#[clap(flatten)]
|
||||
pub build_args: Target::BuildInput,
|
||||
pub build_args: BuildDescription<Target>,
|
||||
|
||||
#[clap(flatten)]
|
||||
pub output_path: OutputPath<Target>,
|
||||
//
|
||||
// #[clap(name = Target::UPLOAD_ASSET_NAME, long)]
|
||||
// pub upload_asset: bool,
|
||||
}
|
||||
|
||||
/// Discriminator denoting how some target artifact should be obtained.
|
||||
@ -258,11 +261,20 @@ impl<Target: IsTargetSource> AsRef<Path> for OutputPath<Target> {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, PartialEq, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildDescription<Target: IsTargetSource> {
|
||||
#[clap(flatten)]
|
||||
pub input: Target::BuildInput,
|
||||
#[clap(name = Target::UPLOAD_ARTIFACT_NAME, long, enso_env(), default_value_t = ide_ci::actions::workflow::is_in_env())]
|
||||
pub upload_artifact: bool,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, PartialEq, Derivative)]
|
||||
#[derivative(Debug)]
|
||||
pub struct BuildJob<Target: IsTargetSource> {
|
||||
#[clap(flatten)]
|
||||
pub input: Target::BuildInput,
|
||||
pub input: BuildDescription<Target>,
|
||||
#[clap(flatten)]
|
||||
pub output_path: OutputPath<Target>,
|
||||
}
|
||||
|
35
build/cli/src/arg/gui2.rs
Normal file
35
build/cli/src/arg/gui2.rs
Normal file
@ -0,0 +1,35 @@
|
||||
use enso_build::prelude::*;
|
||||
|
||||
use crate::arg::BuildJob;
|
||||
use crate::arg::Source;
|
||||
use crate::source_args_hlp;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Gui2, "gui2", BuildInput);
|
||||
|
||||
#[derive(Args, Clone, Copy, Debug, PartialEq)]
|
||||
pub struct BuildInput {}
|
||||
|
||||
#[derive(Subcommand, Clone, Debug, PartialEq)]
|
||||
pub enum Command {
|
||||
/// Builds the GUI from the local sources.
|
||||
Build(BuildJob<Gui2>),
|
||||
/// Gets the GUI, either by compiling it from scratch or downloading from an external source.
|
||||
Get(Source<Gui2>),
|
||||
/// Runs the GUI's unit tests.
|
||||
Test,
|
||||
/// Run linter on the GUI's sources.
|
||||
Lint,
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct Target {
|
||||
/// Command for GUI package.
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::arg::IsTargetSource;
|
||||
use crate::arg::OutputPath;
|
||||
use crate::arg::Source;
|
||||
use crate::arg::WatchJob;
|
||||
@ -14,10 +15,10 @@ use octocrab::models::ReleaseId;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Target, "ide", BuildInput);
|
||||
source_args_hlp!(Target, "ide", BuildInput<Gui>);
|
||||
|
||||
#[derive(Args, Clone, Debug, PartialEq)]
|
||||
pub struct BuildInput {
|
||||
pub struct BuildInput<Gui: IsTargetSource> {
|
||||
#[clap(flatten)]
|
||||
pub gui: Source<Gui>,
|
||||
#[clap(flatten)]
|
||||
@ -36,18 +37,18 @@ pub enum Command {
|
||||
/// application.
|
||||
Build {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
params: BuildInput<Gui>,
|
||||
},
|
||||
Upload {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
params: BuildInput<Gui>,
|
||||
#[clap(long, env = *enso_build::env::ENSO_RELEASE_ID)]
|
||||
release_id: ReleaseId,
|
||||
},
|
||||
/// Like `Build` but automatically starts the IDE.
|
||||
Start {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
params: BuildInput<Gui>,
|
||||
/// Additional option to be passed to Enso IDE. Can be used multiple times to pass many
|
||||
/// arguments.
|
||||
#[clap(long, allow_hyphen_values = true, enso_env())]
|
||||
|
29
build/cli/src/arg/ide2.rs
Normal file
29
build/cli/src/arg/ide2.rs
Normal file
@ -0,0 +1,29 @@
|
||||
use crate::prelude::*;
|
||||
|
||||
use crate::source_args_hlp;
|
||||
|
||||
use clap::Args;
|
||||
use clap::Subcommand;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
|
||||
|
||||
|
||||
source_args_hlp!(Target, "ide2", BuildInput);
|
||||
|
||||
pub type BuildInput = crate::arg::ide::BuildInput<Gui2>;
|
||||
|
||||
#[derive(Subcommand, Clone, Debug)]
|
||||
pub enum Command {
|
||||
/// Builds both Project Manager and GUI, puts them together into a single, client Electron
|
||||
/// application.
|
||||
Build {
|
||||
#[clap(flatten)]
|
||||
params: BuildInput,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args, Clone, Debug)]
|
||||
pub struct Target {
|
||||
#[clap(subcommand)]
|
||||
pub command: Command,
|
||||
}
|
@ -38,9 +38,11 @@ use crate::arg::BuildJob;
|
||||
use crate::arg::Cli;
|
||||
use crate::arg::IsTargetSource;
|
||||
use crate::arg::IsWatchableSource;
|
||||
use crate::arg::OutputPath;
|
||||
use crate::arg::Target;
|
||||
use crate::arg::WatchJob;
|
||||
use anyhow::Context;
|
||||
use arg::BuildDescription;
|
||||
use clap::Parser;
|
||||
use derivative::Derivative;
|
||||
use enso_build::context::BuildContext;
|
||||
@ -53,15 +55,20 @@ use enso_build::project::backend;
|
||||
use enso_build::project::backend::Backend;
|
||||
use enso_build::project::gui;
|
||||
use enso_build::project::gui::Gui;
|
||||
use enso_build::project::gui2;
|
||||
use enso_build::project::gui2::Gui2;
|
||||
use enso_build::project::ide;
|
||||
use enso_build::project::ide::Ide;
|
||||
use enso_build::project::ide2;
|
||||
use enso_build::project::runtime;
|
||||
use enso_build::project::runtime::Runtime;
|
||||
use enso_build::project::wasm;
|
||||
use enso_build::project::wasm::Wasm;
|
||||
use enso_build::project::IsArtifact;
|
||||
use enso_build::project::IsTarget;
|
||||
use enso_build::project::IsWatchable;
|
||||
use enso_build::project::IsWatcher;
|
||||
use enso_build::source::BuildSource;
|
||||
use enso_build::source::BuildTargetJob;
|
||||
use enso_build::source::CiRunSource;
|
||||
use enso_build::source::ExternalSource;
|
||||
@ -85,7 +92,6 @@ use ide_ci::programs::git;
|
||||
use ide_ci::programs::git::clean;
|
||||
use ide_ci::programs::rustc;
|
||||
use ide_ci::programs::Cargo;
|
||||
use ide_ci::programs::Npm;
|
||||
use std::time::Duration;
|
||||
use tempfile::tempdir;
|
||||
use tokio::process::Child;
|
||||
@ -131,7 +137,6 @@ impl Processor {
|
||||
inner: project::Context {
|
||||
cache: Cache::new(&cli.cache_path).await?,
|
||||
octocrab,
|
||||
upload_artifacts: cli.upload_artifacts,
|
||||
repo_root: enso_build::paths::new_repo_root(absolute_repo_path, &triple),
|
||||
},
|
||||
triple,
|
||||
@ -154,9 +159,13 @@ impl Processor {
|
||||
{
|
||||
let span = info_span!("Resolving.", ?target, ?source).entered();
|
||||
let destination = source.output_path.output_path;
|
||||
let should_upload_artifact = source.build_args.upload_artifact;
|
||||
let source = match source.source {
|
||||
arg::SourceKind::Build =>
|
||||
T::resolve(self, source.build_args).map_ok(Source::BuildLocally).boxed(),
|
||||
arg::SourceKind::Build => T::resolve(self, source.build_args.input)
|
||||
.map_ok(move |input| {
|
||||
Source::BuildLocally(BuildSource { input, should_upload_artifact })
|
||||
})
|
||||
.boxed(),
|
||||
arg::SourceKind::Local =>
|
||||
ok_ready_boxed(Source::External(ExternalSource::LocalFile(source.path))),
|
||||
arg::SourceKind::CiRun => {
|
||||
@ -243,10 +252,16 @@ impl Processor {
|
||||
&self,
|
||||
job: BuildJob<T>,
|
||||
) -> BoxFuture<'static, Result<BuildTargetJob<T>>> {
|
||||
let BuildJob { input, output_path } = job;
|
||||
let BuildJob { input: BuildDescription { input, upload_artifact }, output_path } = job;
|
||||
let input = self.resolve_inputs::<T>(input);
|
||||
async move {
|
||||
Ok(WithDestination { destination: output_path.output_path, inner: input.await? })
|
||||
Ok(WithDestination::new(
|
||||
BuildSource {
|
||||
input: input.await?,
|
||||
should_upload_artifact: upload_artifact,
|
||||
},
|
||||
output_path.output_path,
|
||||
))
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
@ -320,17 +335,6 @@ impl Processor {
|
||||
}
|
||||
}
|
||||
|
||||
// pub fn handle_engine(&self, engine: arg::engine::Target) -> BoxFuture<'static, Result> {
|
||||
// self.get(engine.source).void_ok().boxed()
|
||||
// }
|
||||
//
|
||||
// pub fn handle_project_manager(
|
||||
// &self,
|
||||
// project_manager: arg::project_manager::Target,
|
||||
// ) -> BoxFuture<'static, Result> {
|
||||
// self.get(project_manager.source).void_ok().boxed()
|
||||
// }
|
||||
|
||||
pub fn handle_gui(&self, gui: arg::gui::Target) -> BoxFuture<'static, Result> {
|
||||
match gui.command {
|
||||
arg::gui::Command::Build(job) => self.build(job),
|
||||
@ -339,6 +343,15 @@ impl Processor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_gui2(&self, gui: arg::gui2::Target) -> BoxFuture<'static, Result> {
|
||||
match gui.command {
|
||||
arg::gui2::Command::Build(job) => self.build(job),
|
||||
arg::gui2::Command::Get(source) => self.get(source).void_ok().boxed(),
|
||||
arg::gui2::Command::Test => gui2::unit_tests(&self.repo_root),
|
||||
arg::gui2::Command::Lint => gui2::lint(&self.repo_root),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_runtime(&self, gui: arg::runtime::Target) -> BoxFuture<'static, Result> {
|
||||
// todo!()
|
||||
match gui.command {
|
||||
@ -439,8 +452,7 @@ impl Processor {
|
||||
};
|
||||
let context = self.prepare_backend_context(config);
|
||||
async move {
|
||||
let mut context = context.await?;
|
||||
context.upload_artifacts = true;
|
||||
let context = context.await?;
|
||||
context.build().await
|
||||
}
|
||||
.void_ok()
|
||||
@ -461,7 +473,7 @@ impl Processor {
|
||||
let paths = paths?;
|
||||
let inner = crate::project::Context {
|
||||
repo_root: paths.repo_root.clone(),
|
||||
upload_artifacts: true,
|
||||
// upload_artifacts: true,
|
||||
octocrab,
|
||||
cache: Cache::new_default().await?,
|
||||
};
|
||||
@ -472,9 +484,9 @@ impl Processor {
|
||||
|
||||
pub fn handle_ide(&self, ide: arg::ide::Target) -> BoxFuture<'static, Result> {
|
||||
match ide.command {
|
||||
arg::ide::Command::Build { params } => self.build_ide(params).void_ok().boxed(),
|
||||
arg::ide::Command::Build { params } => self.build_old_ide(params).void_ok().boxed(),
|
||||
arg::ide::Command::Upload { params, release_id } => {
|
||||
let build_job = self.build_ide(params);
|
||||
let build_job = self.build_old_ide(params);
|
||||
let release = ide_ci::github::release::Handle::new(
|
||||
&self.octocrab,
|
||||
self.remote_repo.clone(),
|
||||
@ -489,7 +501,7 @@ impl Processor {
|
||||
.boxed()
|
||||
}
|
||||
arg::ide::Command::Start { params, ide_option } => {
|
||||
let build_job = self.build_ide(params);
|
||||
let build_job = self.build_old_ide(params);
|
||||
async move {
|
||||
let ide = build_job.await?;
|
||||
ide.start_unpacked(ide_option).run_ok().await?;
|
||||
@ -547,6 +559,12 @@ impl Processor {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_ide2(&self, ide: arg::ide2::Target) -> BoxFuture<'static, Result> {
|
||||
match ide.command {
|
||||
arg::ide2::Command::Build { params } => self.build_new_ide(params).void_ok().boxed(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Spawns a Project Manager.
|
||||
pub fn spawn_project_manager(
|
||||
&self,
|
||||
@ -566,10 +584,27 @@ impl Processor {
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn build_ide(
|
||||
&self,
|
||||
params: arg::ide::BuildInput,
|
||||
input: ide::BuildInput<impl IsArtifact>,
|
||||
output_path: OutputPath<arg::ide::Target>,
|
||||
) -> BoxFuture<'static, Result<ide::Artifact>> {
|
||||
let target = Ide { target_os: self.triple.os, target_arch: self.triple.arch };
|
||||
let artifact_name_prefix = input.artifact_name.clone();
|
||||
let build_job = target.build(&self.context, input, output_path);
|
||||
async move {
|
||||
let artifacts = build_job.await?;
|
||||
if is_in_env() {
|
||||
artifacts.upload_as_ci_artifact(artifact_name_prefix).await?;
|
||||
}
|
||||
Ok(artifacts)
|
||||
}
|
||||
.boxed()
|
||||
}
|
||||
|
||||
pub fn build_old_ide(
|
||||
&self,
|
||||
params: arg::ide::BuildInput<Gui>,
|
||||
) -> BoxFuture<'static, Result<ide::Artifact>> {
|
||||
let arg::ide::BuildInput { gui, project_manager, output_path, electron_target } = params;
|
||||
let input = ide::BuildInput {
|
||||
@ -577,17 +612,39 @@ impl Processor {
|
||||
project_manager: self.get(project_manager),
|
||||
version: self.triple.versions.version.clone(),
|
||||
electron_target,
|
||||
artifact_name: "ide".into(),
|
||||
};
|
||||
let target = Ide { target_os: self.triple.os, target_arch: self.triple.arch };
|
||||
let build_job = target.build(&self.context, input, output_path);
|
||||
async move {
|
||||
let artifacts = build_job.await?;
|
||||
if is_in_env() {
|
||||
artifacts.upload_as_ci_artifact().await?;
|
||||
self.build_ide(input, output_path)
|
||||
}
|
||||
|
||||
pub fn build_new_ide(
|
||||
&self,
|
||||
params: arg::ide2::BuildInput,
|
||||
) -> BoxFuture<'static, Result<ide2::Artifact>> {
|
||||
let arg::ide::BuildInput { gui, project_manager, output_path, electron_target } = params;
|
||||
|
||||
let build_info_get = self.js_build_info();
|
||||
let build_info_path = self.context.inner.repo_root.join(&*enso_build::ide::web::BUILD_INFO);
|
||||
|
||||
let build_info = async move {
|
||||
let build_info = build_info_get.await?;
|
||||
build_info_path.write_as_json(&build_info)
|
||||
};
|
||||
|
||||
let gui = self.get(gui);
|
||||
|
||||
let input = ide::BuildInput {
|
||||
gui: async move {
|
||||
build_info.await?;
|
||||
gui.await
|
||||
}
|
||||
Ok(artifacts)
|
||||
}
|
||||
.boxed()
|
||||
.boxed(),
|
||||
project_manager: self.get(project_manager),
|
||||
version: self.triple.versions.version.clone(),
|
||||
electron_target,
|
||||
artifact_name: "ide2".into(),
|
||||
};
|
||||
self.build_ide(input, output_path)
|
||||
}
|
||||
|
||||
pub fn target<Target: Resolvable>(&self) -> Result<Target> {
|
||||
@ -655,6 +712,19 @@ impl Resolvable for Gui {
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolvable for Gui2 {
|
||||
fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
Ok(Gui2)
|
||||
}
|
||||
|
||||
fn resolve(
|
||||
_ctx: &Processor,
|
||||
_from: <Self as IsTargetSource>::BuildInput,
|
||||
) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>> {
|
||||
ok_ready_boxed(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Resolvable for Runtime {
|
||||
fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
Ok(Runtime {})
|
||||
@ -696,42 +766,9 @@ impl Resolvable for Backend {
|
||||
Ok(backend::BuildInput { external_runtime, versions })
|
||||
})
|
||||
.boxed()
|
||||
// ok_ready_boxed(backend::BuildInput { versions: ctx.triple.versions.clone() })
|
||||
}
|
||||
}
|
||||
|
||||
// impl Resolvable for ProjectManager {
|
||||
// fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
// Ok(ProjectManager)
|
||||
// }
|
||||
//
|
||||
// fn resolve(
|
||||
// ctx: &Processor,
|
||||
// _from: <Self as IsTargetSource>::BuildInput,
|
||||
// ) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>> {
|
||||
// ok_ready_boxed(project_manager::BuildInput {
|
||||
// repo_root: ctx.repo_root().path,
|
||||
// versions: ctx.triple.versions.clone(),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// impl Resolvable for Engine {
|
||||
// fn prepare_target(_context: &Processor) -> Result<Self> {
|
||||
// Ok(Engine)
|
||||
// }
|
||||
//
|
||||
// fn resolve(
|
||||
// ctx: &Processor,
|
||||
// _from: <Self as IsTargetSource>::BuildInput,
|
||||
// ) -> BoxFuture<'static, Result<<Self as IsTarget>::BuildInput>> {
|
||||
// ok_ready_boxed(engine::BuildInput {
|
||||
// repo_root: ctx.repo_root().path,
|
||||
// versions: ctx.triple.versions.clone(),
|
||||
// })
|
||||
// }
|
||||
// }
|
||||
|
||||
pub trait WatchResolvable: Resolvable + IsWatchableSource + IsWatchable {
|
||||
fn resolve_watch(
|
||||
ctx: &Processor,
|
||||
@ -777,6 +814,10 @@ pub async fn main_internal(config: Option<enso_build::config::Config>) -> Result
|
||||
|
||||
debug!("Parsed CLI arguments: {cli:#?}");
|
||||
|
||||
if cli.skip_npm_install {
|
||||
enso_build::web::assume_installed();
|
||||
}
|
||||
|
||||
if !cli.skip_version_check {
|
||||
// Let's be helpful!
|
||||
let error_message = "Program requirements were not fulfilled. Please do one of the \
|
||||
@ -796,13 +837,14 @@ pub async fn main_internal(config: Option<enso_build::config::Config>) -> Result
|
||||
match cli.target {
|
||||
Target::Wasm(wasm) => ctx.handle_wasm(wasm).await?,
|
||||
Target::Gui(gui) => ctx.handle_gui(gui).await?,
|
||||
Target::Gui2(gui2) => ctx.handle_gui2(gui2).await?,
|
||||
Target::Runtime(runtime) => ctx.handle_runtime(runtime).await?,
|
||||
// Target::ProjectManager(project_manager) =>
|
||||
// ctx.handle_project_manager(project_manager).await?,
|
||||
// Target::Engine(engine) => ctx.handle_engine(engine).await?,
|
||||
Target::Backend(backend) => ctx.handle_backend(backend).await?,
|
||||
Target::Ide(ide) => ctx.handle_ide(ide).await?,
|
||||
// TODO: consider if out-of-source ./dist should be removed
|
||||
Target::Ide2(ide2) => ctx.handle_ide2(ide2).await?,
|
||||
Target::GitClean(options) => {
|
||||
let crate::arg::git_clean::Options { dry_run, cache, build_script } = options;
|
||||
let mut exclusions = vec![".idea"];
|
||||
@ -852,12 +894,13 @@ pub async fn main_internal(config: Option<enso_build::config::Config>) -> Result
|
||||
.run_ok()
|
||||
.await?;
|
||||
|
||||
Npm.cmd()?.install().run_ok().await?;
|
||||
Npm.cmd()?.run("ci-check").run_ok().await?;
|
||||
enso_build::web::install(&ctx.repo_root).await?;
|
||||
enso_build::web::run_script(&ctx.repo_root, enso_build::web::Script::CiCheck).await?;
|
||||
}
|
||||
Target::Fmt => {
|
||||
Npm.cmd()?.install().run_ok().await?;
|
||||
let prettier = Npm.cmd()?.run("format").run_ok();
|
||||
enso_build::web::install(&ctx.repo_root).await?;
|
||||
let prettier =
|
||||
enso_build::web::run_script(&ctx.repo_root, enso_build::web::Script::Format);
|
||||
let our_formatter =
|
||||
enso_formatter::process_path(&ctx.repo_root, enso_formatter::Action::Format);
|
||||
let (r1, r2) = join!(prettier, our_formatter).await;
|
||||
|
@ -61,7 +61,7 @@
|
||||
//! 1. If the `dist/index.js` file does not exist, or its modification date is older than
|
||||
//! `this_crate/js` sources:
|
||||
//!
|
||||
//! 1. `npm run install` is run in the `this_crate/js` directory.
|
||||
//! 1. `npm install` is assumed to have been already run in the `this_crate/js` directory.
|
||||
//!
|
||||
//! 2. The `this_crate/js/runner` is compiled to `target/ensogl-pack/dist/index.cjs`. This is the
|
||||
//! main file which is capable of loading WASM file, displaying a loading screen, running
|
||||
@ -351,7 +351,6 @@ pub async fn compile_this_crate_ts_sources(paths: &Paths) -> Result<()> {
|
||||
println!("compile_this_crate_ts_sources");
|
||||
if check_if_ts_needs_rebuild(paths)? {
|
||||
info!("EnsoGL Pack TypeScript sources changed, recompiling.");
|
||||
ide_ci::programs::Npm.cmd()?.install().current_dir(&paths.workspace).run_ok().await?;
|
||||
let run_script = async move |script_name, script_args: &[&str]| {
|
||||
ide_ci::programs::Npm
|
||||
.cmd()?
|
||||
@ -378,6 +377,7 @@ pub async fn compile_this_crate_ts_sources(paths: &Paths) -> Result<()> {
|
||||
}
|
||||
|
||||
/// Run wasm-pack to build the wasm artifact.
|
||||
#[context("Failed to run wasm-pack.")]
|
||||
pub async fn run_wasm_pack(
|
||||
paths: &Paths,
|
||||
provider: impl FnOnce(WasmPackOutputs) -> Result<WasmPackCommand>,
|
||||
|
45
package-lock.json
generated
45
package-lock.json
generated
@ -3021,6 +3021,51 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-arm64": {
|
||||
"version": "1.3.85",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-darwin-x64": {
|
||||
"version": "1.3.85",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-linux-x64-gnu": {
|
||||
"version": "1.3.85",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "Apache-2.0 AND MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@swc/core-win32-x64-msvc": {
|
||||
"version": "1.3.85",
|
||||
"cpu": [
|
||||
|
Loading…
Reference in New Issue
Block a user