mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-07 19:36:31 +00:00
Merge pull request #3819 from balena-io/ab77/operational
Switch to Flowzone
This commit is contained in:
commit
a40e64f6cd
7
.gitattributes
vendored
7
.gitattributes
vendored
@ -1,3 +1,6 @@
|
|||||||
|
# default
|
||||||
|
* text
|
||||||
|
|
||||||
# Javascript files must retain LF line-endings (to keep eslint happy)
|
# Javascript files must retain LF line-endings (to keep eslint happy)
|
||||||
*.js text eol=lf
|
*.js text eol=lf
|
||||||
*.jsx text eol=lf
|
*.jsx text eol=lf
|
||||||
@ -59,3 +62,7 @@ CODEOWNERS text
|
|||||||
*.ttf binary diff=hex
|
*.ttf binary diff=hex
|
||||||
xz-without-extension binary diff=hex
|
xz-without-extension binary diff=hex
|
||||||
wmic-output.txt binary diff=hex
|
wmic-output.txt binary diff=hex
|
||||||
|
|
||||||
|
# gitsecret
|
||||||
|
*.secret binary
|
||||||
|
.gitsecret/** binary
|
||||||
|
48
.github/actions/finalize/action.yml
vendored
Normal file
48
.github/actions/finalize/action.yml
vendored
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
---
|
||||||
|
name: publish GitHub release
|
||||||
|
# https://github.com/product-os/flowzone/tree/master/.github/actions
|
||||||
|
inputs:
|
||||||
|
json:
|
||||||
|
description: "JSON stringified object containing all the inputs from the calling workflow"
|
||||||
|
required: true
|
||||||
|
secrets:
|
||||||
|
description: "JSON stringified object containing all the secrets from the calling workflow"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Get release version
|
||||||
|
id: get_release
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
echo "version=$(jq -r '.version' package.json)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Rename release
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
gh release edit '${{ github.event.pull_request.head.ref }}' \
|
||||||
|
--title 'v${{ steps.get_release.outputs.version }}' \
|
||||||
|
--tag 'v${{ steps.get_release.outputs.version }}'
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ fromJSON(inputs.secrets).FLOWZONE_TOKEN }}
|
||||||
|
|
||||||
|
- name: Finalize GitHub release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
name: v${{ steps.get_release.outputs.version }}
|
||||||
|
tag_name: v${{ steps.get_release.outputs.version }}
|
||||||
|
draft: false
|
||||||
|
generate_release_notes: true
|
||||||
|
prerelease: false
|
||||||
|
token: ${{ fromJSON(inputs.secrets).FLOWZONE_TOKEN }}
|
251
.github/actions/publish/action.yml
vendored
Normal file
251
.github/actions/publish/action.yml
vendored
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
---
|
||||||
|
name: package and publish GitHub (draft) release
|
||||||
|
# https://github.com/product-os/flowzone/tree/master/.github/actions
|
||||||
|
inputs:
|
||||||
|
json:
|
||||||
|
description: "JSON stringified object containing all the inputs from the calling workflow"
|
||||||
|
required: true
|
||||||
|
secrets:
|
||||||
|
description: "JSON stringified object containing all the secrets from the calling workflow"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
# --- custom environment
|
||||||
|
XCODE_APP_LOADER_EMAIL:
|
||||||
|
type: string
|
||||||
|
default: "accounts+apple@balena.io"
|
||||||
|
NODE_VERSION:
|
||||||
|
type: string
|
||||||
|
default: "14.x"
|
||||||
|
VERBOSE:
|
||||||
|
type: string
|
||||||
|
default: "true"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Download custom source artifact
|
||||||
|
uses: actions/download-artifact@v3
|
||||||
|
with:
|
||||||
|
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}
|
||||||
|
path: ${{ runner.temp }}
|
||||||
|
|
||||||
|
- name: Extract custom source artifact
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
working-directory: .
|
||||||
|
run: tar -xf ${{ runner.temp }}/custom.tgz
|
||||||
|
|
||||||
|
- name: Extract custom source artifact
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: powershell
|
||||||
|
working-directory: .
|
||||||
|
run: tar -xf ${{ runner.temp }}\custom.tgz
|
||||||
|
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ inputs.NODE_VERSION }}
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Install yq
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: choco install yq
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
|
||||||
|
# FIXME: resinci-deploy is not actively maintained
|
||||||
|
# https://github.com/product-os/resinci-deploy
|
||||||
|
- name: Checkout resinci-deploy
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: product-os/resinci-deploy
|
||||||
|
token: ${{ fromJSON(inputs.secrets).FLOWZONE_TOKEN }}
|
||||||
|
path: resinci-deploy
|
||||||
|
|
||||||
|
- name: Build and install resinci-deploy
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
runner_os="$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
|
rm -rf ../resinci-deploy && mv resinci-deploy ..
|
||||||
|
|
||||||
|
pushd ../resinci-deploy && npm ci && npm link && popd
|
||||||
|
|
||||||
|
if [ $runner_os =~ linux|macos ]]; then
|
||||||
|
chmod +x "$(dirname "$(which node)")/resinci-deploy" && which resinci-deploy
|
||||||
|
fi
|
||||||
|
|
||||||
|
# FIXME: store sentry workflow is not documented
|
||||||
|
# https://github.com/product-os/resinci-deploy/blob/master/lib/sentry.ts
|
||||||
|
# https://github.com/getsentry/sentry-cli
|
||||||
|
# https://docs.sentry.io/api/projects/create-a-new-client-key/
|
||||||
|
- name: Generate Sentry DSN
|
||||||
|
id: sentry
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
branch="$(echo '${{ github.event.pull_request.head.ref }}' | sed 's/[^[:alnum:]]/-/g')"
|
||||||
|
|
||||||
|
stdout="$(resinci-deploy store sentry \
|
||||||
|
--branch="${branch}" \
|
||||||
|
--name="$(jq -r '.name' package.json)" \
|
||||||
|
--team="$(yq e '.sentry.team' repo.yml)" \
|
||||||
|
--org="$(yq e '.sentry.org' repo.yml)" \
|
||||||
|
--type="$(yq e '.sentry.type' repo.yml)")"
|
||||||
|
|
||||||
|
echo "dsn=$(echo "${stdout}" | tail -n 1)" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
env:
|
||||||
|
SENTRY_TOKEN: ${{ fromJSON(inputs.secrets).SENTRY_AUTH_TOKEN }}
|
||||||
|
|
||||||
|
# https://www.electron.build/code-signing.html
|
||||||
|
# https://github.com/Apple-Actions/import-codesign-certs
|
||||||
|
- name: Import Apple code signing certificate
|
||||||
|
if: runner.os == 'macOS'
|
||||||
|
uses: apple-actions/import-codesign-certs@v1
|
||||||
|
with:
|
||||||
|
p12-file-base64: ${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
|
||||||
|
p12-password: ${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Import Windows code signing certificate
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: powershell
|
||||||
|
run: |
|
||||||
|
Set-Content -Path ${{ runner.temp }}/certificate.base64 -Value $env:WINDOWS_CERTIFICATE
|
||||||
|
certutil -decode ${{ runner.temp }}/certificate.base64 ${{ runner.temp }}/certificate.pfx
|
||||||
|
Remove-Item -path ${{ runner.temp }} -include certificate.base64
|
||||||
|
|
||||||
|
Import-PfxCertificate `
|
||||||
|
-FilePath ${{ runner.temp }}/certificate.pfx `
|
||||||
|
-CertStoreLocation Cert:\CurrentUser\My `
|
||||||
|
-Password (ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText)
|
||||||
|
|
||||||
|
Remove-Item -path ${{ runner.temp }} -include certificate.pfx
|
||||||
|
|
||||||
|
env:
|
||||||
|
WINDOWS_CERTIFICATE: ${{ fromJSON(inputs.secrets).WINDOWS_SIGNING }}
|
||||||
|
WINDOWS_CERTIFICATE_PASSWORD: ${{ fromJSON(inputs.secrets).WINDOWS_SIGNING_PASSWORD }}
|
||||||
|
|
||||||
|
# ... or refactor (e.g.) https://github.com/samuelmeuli/action-electron-builder
|
||||||
|
# https://github.com/product-os/scripts/tree/master/electron
|
||||||
|
# https://github.com/product-os/scripts/tree/master/shared
|
||||||
|
# https://github.com/product-os/balena-concourse/blob/master/pipelines/github-events/template.yml
|
||||||
|
- name: Package release
|
||||||
|
id: package_release
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
runner_os="$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
runner_arch="$(echo "${RUNNER_ARCH}" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
|
ELECTRON_BUILDER_ARCHITECTURE="${runner_arch}"
|
||||||
|
APPLICATION_VERSION="$(jq -r '.version' package.json)"
|
||||||
|
ARCHITECTURE_FLAGS="--${ELECTRON_BUILDER_ARCHITECTURE}"
|
||||||
|
|
||||||
|
if [[ $runner_os =~ linux ]]; then
|
||||||
|
ELECTRON_BUILDER_OS='--linux'
|
||||||
|
TARGETS="$(yq e .linux.target[] electron-builder.yml)"
|
||||||
|
|
||||||
|
elif [[ $runner_os =~ darwin|macos|osx ]]; then
|
||||||
|
CSC_KEY_PASSWORD=${{ fromJSON(inputs.secrets).APPLE_SIGNING_PASSWORD }}
|
||||||
|
CSC_KEYCHAIN=signing_temp
|
||||||
|
CSC_LINK=${{ fromJSON(inputs.secrets).APPLE_SIGNING }}
|
||||||
|
ELECTRON_BUILDER_OS='--mac'
|
||||||
|
TARGETS="$(yq e .mac.target[] electron-builder.yml)"
|
||||||
|
|
||||||
|
elif [[ $runner_os =~ windows|win ]]; then
|
||||||
|
ARCHITECTURE_FLAGS="--ia32 ${ARCHITECTURE_FLAGS}"
|
||||||
|
CSC_KEY_PASSWORD=${{ fromJSON(inputs.secrets).WINDOWS_SIGNING_PASSWORD }}
|
||||||
|
CSC_LINK=${{ fromJSON(inputs.secrets).WINDOWS_SIGNING }}
|
||||||
|
ELECTRON_BUILDER_OS='--win'
|
||||||
|
TARGETS="$(yq e .win.target[] electron-builder.yml)"
|
||||||
|
|
||||||
|
else
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
npm link electron-builder
|
||||||
|
|
||||||
|
for target in ${TARGETS}; do
|
||||||
|
electron-builder ${ELECTRON_BUILDER_OS} ${ARCHITECTURE_FLAGS} \
|
||||||
|
--c.extraMetadata.analytics.sentry.token='${{ steps.sentry.outputs.dsn }}' \
|
||||||
|
--c.extraMetadata.packageType="${target}"
|
||||||
|
|
||||||
|
find dist -type f -maxdepth 1
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "version=${APPLICATION_VERSION}" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Apple notarization (afterSignHook.js)
|
||||||
|
XCODE_APP_LOADER_EMAIL: ${{ inputs.XCODE_APP_LOADER_EMAIL }}
|
||||||
|
XCODE_APP_LOADER_PASSWORD: ${{ fromJSON(inputs.secrets).XCODE_APP_LOADER_PASSWORD }}
|
||||||
|
# https://github.blog/2020-08-03-github-actions-improvements-for-fork-and-pull-request-workflows/#improvements-for-public-repository-forks
|
||||||
|
# https://docs.github.com/en/actions/managing-workflow-runs/approving-workflow-runs-from-public-forks#about-workflow-runs-from-public-forks
|
||||||
|
CSC_FOR_PULL_REQUEST: true
|
||||||
|
|
||||||
|
# https://www.electron.build/auto-update.html#staged-rollouts
|
||||||
|
- name: Configure staged rollout(s)
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
percentage="$(cat < repo.yml | yq e .triggerNotification.stagingPercentage)"
|
||||||
|
|
||||||
|
find dist -type f -maxdepth 1 \
|
||||||
|
-name "latest*.yml" \
|
||||||
|
-exec yq -i e .version=\"${{ steps.package_release.outputs.version }}\" {} \;
|
||||||
|
|
||||||
|
find dist -type f -maxdepth 1 \
|
||||||
|
-name "latest*.yml" \
|
||||||
|
-exec yq -i e .stagingPercentage=\"$percentage\" {} \;
|
||||||
|
|
||||||
|
# https://github.com/softprops/action-gh-release#-customizing
|
||||||
|
- name: Create draft GitHub (pre)release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
# use PR branch name for draft releases
|
||||||
|
name: ${{ github.event.pull_request.head.ref }}
|
||||||
|
tag_name: ${{ github.event.pull_request.head.ref }}
|
||||||
|
draft: true
|
||||||
|
generate_release_notes: false
|
||||||
|
prerelease: true
|
||||||
|
token: ${{ fromJSON(inputs.secrets).FLOWZONE_TOKEN }}
|
||||||
|
files: |
|
||||||
|
dist/*.AppImage
|
||||||
|
dist/*.blockmap
|
||||||
|
dist/*.deb
|
||||||
|
dist/*.dmg
|
||||||
|
dist/*.exe
|
||||||
|
dist/*.rpm
|
||||||
|
dist/*.zip
|
||||||
|
dist/latest*.yml
|
||||||
|
|
||||||
|
- name: Compress custom source
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: tar -acf ${{ runner.temp }}/custom.tgz .
|
||||||
|
|
||||||
|
- name: Compress custom source
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: powershell
|
||||||
|
run: tar -acf ${{ runner.temp }}\custom.tgz .
|
||||||
|
|
||||||
|
- name: Upload custom artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}
|
||||||
|
path: ${{ runner.temp }}/custom.tgz
|
||||||
|
retention-days: 1
|
76
.github/actions/test/action.yml
vendored
Normal file
76
.github/actions/test/action.yml
vendored
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
name: test release
|
||||||
|
# https://github.com/product-os/flowzone/tree/master/.github/actions
|
||||||
|
inputs:
|
||||||
|
json:
|
||||||
|
description: "JSON stringified object containing all the inputs from the calling workflow"
|
||||||
|
required: true
|
||||||
|
secrets:
|
||||||
|
description: "JSON stringified object containing all the secrets from the calling workflow"
|
||||||
|
required: true
|
||||||
|
|
||||||
|
# --- custom environment
|
||||||
|
NODE_VERSION:
|
||||||
|
type: string
|
||||||
|
default: "14.x"
|
||||||
|
VERBOSE:
|
||||||
|
type: string
|
||||||
|
default: "true"
|
||||||
|
|
||||||
|
runs:
|
||||||
|
# https://docs.github.com/en/actions/creating-actions/creating-a-composite-action
|
||||||
|
using: "composite"
|
||||||
|
steps:
|
||||||
|
- name: Delete previous draft release
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
gh release delete --yes '${{ github.event.pull_request.head.ref }}' || true
|
||||||
|
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ fromJSON(inputs.secrets).FLOWZONE_TOKEN }}
|
||||||
|
|
||||||
|
# https://github.com/actions/setup-node#caching-global-packages-data
|
||||||
|
- name: Setup Node.js
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ inputs.NODE_VERSION }}
|
||||||
|
cache: npm
|
||||||
|
|
||||||
|
- name: Test release
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: |
|
||||||
|
set -ea
|
||||||
|
|
||||||
|
[[ '${{ inputs.VERBOSE }}' =~ on|On|Yes|yes|true|True ]] && set -x
|
||||||
|
|
||||||
|
runner_os="$(echo "${RUNNER_OS}" | tr '[:upper:]' '[:lower:]')"
|
||||||
|
|
||||||
|
npm run flowzone-preinstall-${runner_os}
|
||||||
|
npm ci
|
||||||
|
npm run build
|
||||||
|
npm run test-${runner_os}
|
||||||
|
|
||||||
|
env:
|
||||||
|
# https://www.electronjs.org/docs/latest/api/environment-variables
|
||||||
|
ELECTRON_NO_ATTACH_CONSOLE: true
|
||||||
|
|
||||||
|
- name: Compress custom source
|
||||||
|
if: runner.os != 'Windows'
|
||||||
|
shell: bash --noprofile --norc -eo pipefail -x {0}
|
||||||
|
run: tar -acf ${{ runner.temp }}/custom.tgz .
|
||||||
|
|
||||||
|
- name: Compress custom source
|
||||||
|
if: runner.os == 'Windows'
|
||||||
|
shell: powershell
|
||||||
|
run: tar -acf ${{ runner.temp }}\custom.tgz .
|
||||||
|
|
||||||
|
- name: Upload custom artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: custom-${{ github.event.pull_request.head.sha || github.event.head_commit.id }}-${{ runner.os }}
|
||||||
|
path: ${{ runner.temp }}/custom.tgz
|
||||||
|
retention-days: 1
|
16
.github/workflows/flowzone.yml
vendored
Normal file
16
.github/workflows/flowzone.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
name: Flowzone
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
types: [opened, synchronize, closed]
|
||||||
|
branches:
|
||||||
|
- "main"
|
||||||
|
- "master"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
flowzone:
|
||||||
|
name: Flowzone
|
||||||
|
uses: product-os/flowzone/.github/workflows/flowzone.yml@master
|
||||||
|
secrets: inherit
|
||||||
|
with:
|
||||||
|
tests_run_on: '["ubuntu-latest","macos-latest","windows-2019"]'
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -51,3 +51,9 @@ node_modules
|
|||||||
# VSCode files
|
# VSCode files
|
||||||
|
|
||||||
.vscode
|
.vscode
|
||||||
|
.gitsecret/keys/random_seed
|
||||||
|
!*.secret
|
||||||
|
secrets/APPLE_SIGNING_PASSWORD.txt
|
||||||
|
secrets/WINDOWS_SIGNING_PASSWORD.txt
|
||||||
|
secrets/XCODE_APP_LOADER_PASSWORD.txt
|
||||||
|
secrets/WINDOWS_SIGNING.pfx
|
||||||
|
BIN
.gitsecret/keys/pubring.kbx
Normal file
BIN
.gitsecret/keys/pubring.kbx
Normal file
Binary file not shown.
BIN
.gitsecret/keys/pubring.kbx~
Normal file
BIN
.gitsecret/keys/pubring.kbx~
Normal file
Binary file not shown.
BIN
.gitsecret/keys/trustdb.gpg
Normal file
BIN
.gitsecret/keys/trustdb.gpg
Normal file
Binary file not shown.
5
.gitsecret/paths/mapping.cfg
Normal file
5
.gitsecret/paths/mapping.cfg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
secrets/APPLE_SIGNING_PASSWORD.txt:5c9cfeb1ea5142b547bc842cc6e0b4a932641ae9811ee47abe2c3953f2a4de5d
|
||||||
|
secrets/WINDOWS_SIGNING_PASSWORD.txt:852e431628494f2559793c39cf09c34e9406dd79bb15b90c9f88194020470568
|
||||||
|
secrets/XCODE_APP_LOADER_PASSWORD.txt:005eb9a3c7035c77232973c9355468fc396b94e62783fb8e6dce16bce95b94a1
|
||||||
|
secrets/WINDOWS_SIGNING.pfx:929f401db38733ffc41572539de7c0d938023af51ed06c205a72a71c1f815714
|
||||||
|
secrets/APPLE_SIGNING.p12:61abf7b4ff2eec76ce889d71bcdd568b99a6a719b4947ac20f03966265b0946a
|
@ -1,74 +0,0 @@
|
|||||||
{
|
|
||||||
"electron": {
|
|
||||||
"npm_version": "6.14.5",
|
|
||||||
"dependencies": {
|
|
||||||
"linux": [
|
|
||||||
"libudev-dev",
|
|
||||||
"libusb-1.0-0-dev",
|
|
||||||
"libyaml-dev",
|
|
||||||
"libgtk-3-0",
|
|
||||||
"libatk-bridge2.0-0",
|
|
||||||
"libdbus-1-3",
|
|
||||||
"libgbm1",
|
|
||||||
"libc6"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"builder": {
|
|
||||||
"appId": "io.balena.etcher",
|
|
||||||
"copyright": "Copyright 2016-2021 Balena Ltd",
|
|
||||||
"productName": "balenaEtcher",
|
|
||||||
"nodeGypRebuild": false,
|
|
||||||
"afterPack": "./afterPack.js",
|
|
||||||
"asar": false,
|
|
||||||
"files": [
|
|
||||||
"generated",
|
|
||||||
"lib/shared/catalina-sudo/sudo-askpass.osascript.js"
|
|
||||||
],
|
|
||||||
"afterSign": "./afterSignHook.js",
|
|
||||||
"mac": {
|
|
||||||
"category": "public.app-category.developer-tools",
|
|
||||||
"hardenedRuntime": true,
|
|
||||||
"entitlements": "entitlements.mac.plist",
|
|
||||||
"entitlementsInherit": "entitlements.mac.plist",
|
|
||||||
"artifactName": "${productName}-${version}.${ext}"
|
|
||||||
},
|
|
||||||
"dmg": {
|
|
||||||
"iconSize": 110,
|
|
||||||
"contents": [
|
|
||||||
{
|
|
||||||
"x": 140,
|
|
||||||
"y": 245
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"x": 415,
|
|
||||||
"y": 245,
|
|
||||||
"type": "link",
|
|
||||||
"path": "/Applications"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"window": {
|
|
||||||
"width": 544,
|
|
||||||
"height": 407
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"linux": {
|
|
||||||
"category": "Utility",
|
|
||||||
"packageCategory": "utils",
|
|
||||||
"synopsis": "balenaEtcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more."
|
|
||||||
},
|
|
||||||
"deb": {
|
|
||||||
"compression": "bzip2",
|
|
||||||
"priority": "optional",
|
|
||||||
"depends": [
|
|
||||||
"polkit-1-auth-agent | policykit-1-gnome | polkit-kde-1"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"protocols": {
|
|
||||||
"name": "etcher",
|
|
||||||
"schemes": [
|
|
||||||
"etcher"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -10,13 +10,15 @@ async function main(context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const appName = context.packager.appInfo.productFilename
|
const appName = context.packager.appInfo.productFilename
|
||||||
const appleId = 'accounts+apple@balena.io'
|
const appleId = process.env.XCODE_APP_LOADER_EMAIL || 'accounts+apple@balena.io'
|
||||||
|
const appleIdPassword = process.env.XCODE_APP_LOADER_PASSWORD
|
||||||
|
|
||||||
|
// https://github.com/electron/notarize/blob/main/README.md
|
||||||
await notarize({
|
await notarize({
|
||||||
appBundleId: 'io.balena.etcher',
|
appBundleId: 'io.balena.etcher',
|
||||||
appPath: `${appOutDir}/${appName}.app`,
|
appPath: `${appOutDir}/${appName}.app`,
|
||||||
appleId,
|
appleId,
|
||||||
appleIdPassword: `@keychain:Application Loader: ${appleId}`
|
appleIdPassword
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
|
# https://www.electron.build/configuration/configuration
|
||||||
appId: io.balena.etcher
|
appId: io.balena.etcher
|
||||||
copyright: Copyright 2016-2021 Balena Ltd
|
copyright: Copyright 2016-2021 Balena Ltd
|
||||||
productName: balenaEtcher
|
productName: balenaEtcher
|
||||||
npmRebuild: true
|
afterPack: ./afterPack.js
|
||||||
nodeGypRebuild: false
|
afterSign: ./afterSignHook.js
|
||||||
publish: null
|
|
||||||
afterPack: "./afterPack.js"
|
|
||||||
asar: false
|
asar: false
|
||||||
files:
|
files:
|
||||||
- generated
|
- generated
|
||||||
@ -16,6 +15,8 @@ mac:
|
|||||||
entitlements: "entitlements.mac.plist"
|
entitlements: "entitlements.mac.plist"
|
||||||
entitlementsInherit: "entitlements.mac.plist"
|
entitlementsInherit: "entitlements.mac.plist"
|
||||||
artifactName: "${productName}-${version}.${ext}"
|
artifactName: "${productName}-${version}.${ext}"
|
||||||
|
target:
|
||||||
|
- dmg
|
||||||
dmg:
|
dmg:
|
||||||
background: assets/dmg/background.tiff
|
background: assets/dmg/background.tiff
|
||||||
icon: assets/icon.icns
|
icon: assets/icon.icns
|
||||||
@ -32,6 +33,10 @@ dmg:
|
|||||||
height: 405
|
height: 405
|
||||||
win:
|
win:
|
||||||
icon: assets/icon.ico
|
icon: assets/icon.ico
|
||||||
|
target:
|
||||||
|
- zip
|
||||||
|
- nsis
|
||||||
|
- portable
|
||||||
nsis:
|
nsis:
|
||||||
oneClick: true
|
oneClick: true
|
||||||
runAfterFinish: true
|
runAfterFinish: true
|
||||||
@ -44,16 +49,23 @@ portable:
|
|||||||
artifactName: "${productName}-Portable-${version}.${ext}"
|
artifactName: "${productName}-Portable-${version}.${ext}"
|
||||||
requestExecutionLevel: user
|
requestExecutionLevel: user
|
||||||
linux:
|
linux:
|
||||||
|
icon: assets/iconset
|
||||||
|
target:
|
||||||
|
- AppImage
|
||||||
|
- rpm
|
||||||
|
- deb
|
||||||
category: Utility
|
category: Utility
|
||||||
packageCategory: utils
|
packageCategory: utils
|
||||||
executableName: balena-etcher-electron
|
executableName: balena-etcher
|
||||||
synopsis: balenaEtcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more.
|
synopsis: balenaEtcher is a powerful OS image flasher built with web technologies to ensure flashing an SDCard or USB drive is a pleasant and safe experience. It protects you from accidentally writing to your hard-drives, ensures every byte of data was written correctly and much more.
|
||||||
icon: assets/iconset
|
appImage:
|
||||||
|
artifactName: ${productName}-${version}-${env.ELECTRON_BUILDER_ARCHITECTURE}.${ext}
|
||||||
deb:
|
deb:
|
||||||
priority: optional
|
priority: optional
|
||||||
|
compression: bzip2
|
||||||
depends:
|
depends:
|
||||||
- gconf2
|
|
||||||
- gconf-service
|
- gconf-service
|
||||||
|
- gconf2
|
||||||
- libasound2
|
- libasound2
|
||||||
- libatk1.0-0
|
- libatk1.0-0
|
||||||
- libc6
|
- libc6
|
||||||
|
3177
package-lock.json
generated
3177
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
34
package.json
34
package.json
@ -13,21 +13,26 @@
|
|||||||
"url": "git@github.com:balena-io/etcher.git"
|
"url": "git@github.com:balena-io/etcher.git"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint-ts": "balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts",
|
"build": "npm run webpack",
|
||||||
|
"flowzone-preinstall-linux": "sudo apt-get install -y xvfb libudev-dev && cat < electron-builder.yml | yq e .deb.depends[] - | xargs -L1 echo | sed 's/|//g' | xargs -L1 sudo apt-get --ignore-missing install || true",
|
||||||
|
"flowzone-preinstall-macos": "true",
|
||||||
|
"flowzone-preinstall-windows": "true",
|
||||||
|
"flowzone-preinstall": "npm run flowzone-preinstall-linux",
|
||||||
"lint-css": "prettier --write lib/**/*.css",
|
"lint-css": "prettier --write lib/**/*.css",
|
||||||
|
"lint-ts": "balena-lint --fix --typescript typings lib tests scripts/clean-shrinkwrap.ts webpack.config.ts",
|
||||||
"lint": "npm run lint-ts && npm run lint-css",
|
"lint": "npm run lint-ts && npm run lint-css",
|
||||||
"test-spectron": "mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts tests/spectron/runner.spec.ts",
|
"postinstall": "electron-rebuild -t prod,dev,optional",
|
||||||
"test-gui": "electron-mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox --renderer tests/gui/**/*.ts",
|
|
||||||
"test-shared": "electron-mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox tests/shared/**/*.ts",
|
|
||||||
"test": "npm run lint && npm run test-gui && npm run test-shared && npm run test-spectron && npm run sanity-checks",
|
|
||||||
"sanity-checks": "bash scripts/ci/ensure-all-file-extensions-in-gitattributes.sh",
|
"sanity-checks": "bash scripts/ci/ensure-all-file-extensions-in-gitattributes.sh",
|
||||||
"start": "./node_modules/.bin/electron .",
|
"start": "./node_modules/.bin/electron .",
|
||||||
"postinstall": "electron-rebuild -t prod,dev,optional",
|
"test-macos": "npm run lint && npm run test-gui && npm run test-shared && npm run test-spectron && npm run sanity-checks",
|
||||||
"webpack": "webpack",
|
"test-gui": "electron-mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox --renderer tests/gui/**/*.ts",
|
||||||
|
"test-linux": "npm run lint && xvfb-run --auto-servernum npm run test-gui && xvfb-run --auto-servernum npm run test-shared && xvfb-run --auto-servernum npm run test-spectron && npm run sanity-checks",
|
||||||
|
"test-shared": "electron-mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts --full-trace --no-sandbox tests/shared/**/*.ts",
|
||||||
|
"test-spectron": "mocha --recursive --reporter spec --require ts-node/register/transpile-only --require-main tests/gui/allow-renderer-process-reuse.ts tests/spectron/runner.spec.ts",
|
||||||
|
"test-windows": "npm run lint && npm run test-gui && npm run test-shared && npm run test-spectron && npm run sanity-checks",
|
||||||
|
"test": "echo npm run test-{linux,windows,macos}",
|
||||||
"watch": "webpack serve --no-optimization-minimize --config ./webpack.dev.config.ts",
|
"watch": "webpack serve --no-optimization-minimize --config ./webpack.dev.config.ts",
|
||||||
"concourse-build-electron": "npm run webpack",
|
"webpack": "webpack"
|
||||||
"concourse-test": "npx npm@6.14.8 test",
|
|
||||||
"concourse-test-electron": "npx npm@6.14.8 test"
|
|
||||||
},
|
},
|
||||||
"husky": {
|
"husky": {
|
||||||
"hooks": {
|
"hooks": {
|
||||||
@ -63,7 +68,7 @@
|
|||||||
"@types/terser-webpack-plugin": "5.0.2",
|
"@types/terser-webpack-plugin": "5.0.2",
|
||||||
"@types/tmp": "0.2.0",
|
"@types/tmp": "0.2.0",
|
||||||
"@types/webpack-node-externals": "2.5.0",
|
"@types/webpack-node-externals": "2.5.0",
|
||||||
"aws4-axios": "2.2.1",
|
"aws4-axios": "2.4.9",
|
||||||
"chai": "4.2.0",
|
"chai": "4.2.0",
|
||||||
"copy-webpack-plugin": "7.0.0",
|
"copy-webpack-plugin": "7.0.0",
|
||||||
"css-loader": "5.0.1",
|
"css-loader": "5.0.1",
|
||||||
@ -76,7 +81,7 @@
|
|||||||
"electron-rebuild": "3.2.5",
|
"electron-rebuild": "3.2.5",
|
||||||
"electron-updater": "4.3.5",
|
"electron-updater": "4.3.5",
|
||||||
"esbuild-loader": "2.16.0",
|
"esbuild-loader": "2.16.0",
|
||||||
"etcher-sdk": "6.3.0",
|
"etcher-sdk": "7.4.0",
|
||||||
"file-loader": "6.2.0",
|
"file-loader": "6.2.0",
|
||||||
"husky": "4.2.5",
|
"husky": "4.2.5",
|
||||||
"immutable": "3.8.1",
|
"immutable": "3.8.1",
|
||||||
@ -87,7 +92,7 @@
|
|||||||
"native-addon-loader": "2.0.1",
|
"native-addon-loader": "2.0.1",
|
||||||
"node-ipc": "9.1.1",
|
"node-ipc": "9.1.1",
|
||||||
"omit-deep-lodash": "1.1.4",
|
"omit-deep-lodash": "1.1.4",
|
||||||
"outdent": "0.7.1",
|
"outdent": "0.8.0",
|
||||||
"path-is-inside": "1.0.2",
|
"path-is-inside": "1.0.2",
|
||||||
"pnp-webpack-plugin": "1.6.4",
|
"pnp-webpack-plugin": "1.6.4",
|
||||||
"pretty-bytes": "5.3.0",
|
"pretty-bytes": "5.3.0",
|
||||||
@ -115,6 +120,9 @@
|
|||||||
"webpack-cli": "4.2.0",
|
"webpack-cli": "4.2.0",
|
||||||
"webpack-dev-server": "4.5.0"
|
"webpack-dev-server": "4.5.0"
|
||||||
},
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14 < 16"
|
||||||
|
},
|
||||||
"versionist": {
|
"versionist": {
|
||||||
"publishedAt": "2022-04-22T13:10:47.906Z"
|
"publishedAt": "2022-04-22T13:10:47.906Z"
|
||||||
}
|
}
|
||||||
|
13
repo.yml
13
repo.yml
@ -1,17 +1,18 @@
|
|||||||
|
---
|
||||||
type: electron
|
type: electron
|
||||||
release: github
|
release: github
|
||||||
publishMetadata: true
|
publishMetadata: true
|
||||||
sentry:
|
sentry:
|
||||||
org: balenaetcher
|
org: balenaetcher
|
||||||
team: resinio
|
team: resinio
|
||||||
type: electron
|
type: electron
|
||||||
triggerNotification:
|
triggerNotification:
|
||||||
version: 1.7.9
|
version: 1.7.9
|
||||||
stagingPercentage: 100
|
stagingPercentage: 100
|
||||||
upstream:
|
upstream:
|
||||||
- repo: etcher-sdk
|
- repo: etcher-sdk
|
||||||
url: https://github.com/balena-io-modules/etcher-sdk
|
url: https://github.com/balena-io-modules/etcher-sdk
|
||||||
module: 'etcher-sdk'
|
module: etcher-sdk
|
||||||
- repo: sys-class-rgb-led
|
- repo: sys-class-rgb-led
|
||||||
url: https://github.com/balena-io-modules/sys-class-rgb-led
|
url: https://github.com/balena-io-modules/sys-class-rgb-led
|
||||||
module: sys-class-rgb-led
|
module: sys-class-rgb-led
|
||||||
|
BIN
secrets/APPLE_SIGNING.p12.secret
Normal file
BIN
secrets/APPLE_SIGNING.p12.secret
Normal file
Binary file not shown.
BIN
secrets/APPLE_SIGNING_PASSWORD.txt.secret
Normal file
BIN
secrets/APPLE_SIGNING_PASSWORD.txt.secret
Normal file
Binary file not shown.
BIN
secrets/WINDOWS_SIGNING.pfx.secret
Normal file
BIN
secrets/WINDOWS_SIGNING.pfx.secret
Normal file
Binary file not shown.
BIN
secrets/WINDOWS_SIGNING_PASSWORD.txt.secret
Normal file
BIN
secrets/WINDOWS_SIGNING_PASSWORD.txt.secret
Normal file
Binary file not shown.
BIN
secrets/XCODE_APP_LOADER_PASSWORD.txt.secret
Normal file
BIN
secrets/XCODE_APP_LOADER_PASSWORD.txt.secret
Normal file
Binary file not shown.
@ -77,11 +77,63 @@ function renameNodeModules(resourcePath: string) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function findUsbPrebuild(): string[] {
|
||||||
|
const usbPrebuildsFolder = path.join('node_modules', 'usb', 'prebuilds')
|
||||||
|
const prebuildFolders = readdirSync(usbPrebuildsFolder);
|
||||||
|
let bindingFile: string | undefined = 'node.napi.node';
|
||||||
|
const platformFolder = prebuildFolders.find(
|
||||||
|
(f) =>
|
||||||
|
f.startsWith(os.platform()) &&
|
||||||
|
f.indexOf(os.arch()) > -1,
|
||||||
|
);
|
||||||
|
if (platformFolder === undefined) {
|
||||||
|
throw new Error('Could not find usb prebuild. Should try fallback to node-gyp and use /build/Release instead of /prebuilds');
|
||||||
|
}
|
||||||
|
|
||||||
|
const bindingFiles = readdirSync(
|
||||||
|
path.join(usbPrebuildsFolder, platformFolder)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!bindingFiles.length) {
|
||||||
|
throw new Error('Could not find usb prebuild for platform')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindingFiles.length === 1) {
|
||||||
|
bindingFile = bindingFiles[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
// armv6 vs v7 in linux-arm and
|
||||||
|
// glibc vs musl in linux-x64
|
||||||
|
if (bindingFiles.length > 1) {
|
||||||
|
bindingFile = bindingFiles.find((file) => {
|
||||||
|
if (bindingFiles.indexOf('arm') > -1) {
|
||||||
|
const process = require('process')
|
||||||
|
return file.indexOf(process.config.variables.arm_version) > -1
|
||||||
|
} else {
|
||||||
|
return file.indexOf('glibc') > -1
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bindingFile === undefined) {
|
||||||
|
throw new Error('Could not find usb prebuild for platform')
|
||||||
|
}
|
||||||
|
|
||||||
|
return [platformFolder, bindingFile];
|
||||||
|
}
|
||||||
|
|
||||||
|
const [
|
||||||
|
USB_BINDINGS_FOLDER,
|
||||||
|
USB_BINDINGS_FILE,
|
||||||
|
] = findUsbPrebuild();
|
||||||
|
|
||||||
function findLzmaNativeBindingsFolder(): string {
|
function findLzmaNativeBindingsFolder(): string {
|
||||||
const files = readdirSync(path.join('node_modules', 'lzma-native'));
|
const files = readdirSync(
|
||||||
|
path.join('node_modules', 'lzma-native', 'prebuilds'),
|
||||||
|
);
|
||||||
const bindingsFolder = files.find(
|
const bindingsFolder = files.find(
|
||||||
(f) =>
|
(f) =>
|
||||||
f.startsWith('binding-') &&
|
f.startsWith(os.platform()) &&
|
||||||
f.endsWith(env.npm_config_target_arch || os.arch()),
|
f.endsWith(env.npm_config_target_arch || os.arch()),
|
||||||
);
|
);
|
||||||
if (bindingsFolder === undefined) {
|
if (bindingsFolder === undefined) {
|
||||||
@ -210,8 +262,8 @@ const commonConfig = {
|
|||||||
/node_modules\/lzma-native\/index\.js$/,
|
/node_modules\/lzma-native\/index\.js$/,
|
||||||
// remove node-pre-gyp magic from lzma-native
|
// remove node-pre-gyp magic from lzma-native
|
||||||
{
|
{
|
||||||
search: 'require(binding_path)',
|
search: `require('node-gyp-build')(__dirname);`,
|
||||||
replace: `require('./${LZMA_BINDINGS_FOLDER}/lzma_native.node')`,
|
replace: `require('./prebuilds/${LZMA_BINDINGS_FOLDER}/electron.napi.node')`,
|
||||||
},
|
},
|
||||||
// use regular stream module instead of readable-stream
|
// use regular stream module instead of readable-stream
|
||||||
{
|
{
|
||||||
@ -220,9 +272,9 @@ const commonConfig = {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
// remove node-pre-gyp magic from usb
|
// remove node-pre-gyp magic from usb
|
||||||
replace(/node_modules\/@balena.io\/usb\/usb\.js$/, {
|
replace(/node_modules\/usb\/dist\/usb\/bindings\.js$/, {
|
||||||
search: 'require(binding_path)',
|
search: `require('node-gyp-build')(path_1.join(__dirname, '..', '..'));`,
|
||||||
replace: "require('./build/Release/usb_bindings.node')",
|
replace: `require('../../prebuilds/${USB_BINDINGS_FOLDER}/${USB_BINDINGS_FILE}')`,
|
||||||
}),
|
}),
|
||||||
// remove bindings magic from mountutils
|
// remove bindings magic from mountutils
|
||||||
replace(/node_modules\/mountutils\/index\.js$/, {
|
replace(/node_modules\/mountutils\/index\.js$/, {
|
||||||
@ -348,8 +400,8 @@ const guiConfigCopyPatterns = [
|
|||||||
if (os.platform() === 'win32') {
|
if (os.platform() === 'win32') {
|
||||||
// liblzma.dll is required on Windows for lzma-native
|
// liblzma.dll is required on Windows for lzma-native
|
||||||
guiConfigCopyPatterns.push({
|
guiConfigCopyPatterns.push({
|
||||||
from: `node_modules/lzma-native/${LZMA_BINDINGS_FOLDER}/liblzma.dll`,
|
from: `node_modules/lzma-native/prebuilds/${LZMA_BINDINGS_FOLDER}/liblzma.dll`,
|
||||||
to: `modules/lzma-native/${LZMA_BINDINGS_FOLDER_RENAMED}/liblzma.dll`,
|
to: `modules/lzma-native/prebuilds/${LZMA_BINDINGS_FOLDER_RENAMED}/liblzma.dll`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user