Merge pull request #1761 from cdr/static
Stop bundling libraries in release
This commit is contained in:
commit
79d1e179f8
|
@ -8,7 +8,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/fmt.sh
|
- name: Run ./ci/steps/fmt.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/fmt.sh
|
args: ./ci/steps/fmt.sh
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/lint.sh
|
- name: Run ./ci/steps/lint.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/lint.sh
|
args: ./ci/steps/lint.sh
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/test.sh
|
- name: Run ./ci/steps/test.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/test.sh
|
args: ./ci/steps/test.sh
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/release.sh
|
- name: Run ./ci/steps/release.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/release.sh
|
args: ./ci/steps/release.sh
|
||||||
- name: Upload npm package artifact
|
- name: Upload npm package artifact
|
||||||
|
@ -55,7 +55,7 @@ jobs:
|
||||||
name: npm-package
|
name: npm-package
|
||||||
path: ./release-npm-package
|
path: ./release-npm-package
|
||||||
- name: Run ./ci/steps/release-packages.sh
|
- name: Run ./ci/steps/release-packages.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/centos7
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/release-packages.sh
|
args: ./ci/steps/release-packages.sh
|
||||||
- name: Upload release artifacts
|
- name: Upload release artifacts
|
||||||
|
@ -75,7 +75,7 @@ jobs:
|
||||||
name: npm-package
|
name: npm-package
|
||||||
path: ./release-npm-package
|
path: ./release-npm-package
|
||||||
- name: Run ./ci/steps/release-packages.sh
|
- name: Run ./ci/steps/release-packages.sh
|
||||||
uses: ./ci/container/arm64
|
uses: ./ci/images/centos7
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/release-packages.sh
|
args: ./ci/steps/release-packages.sh
|
||||||
- name: Upload release artifacts
|
- name: Upload release artifacts
|
||||||
|
@ -94,8 +94,6 @@ jobs:
|
||||||
with:
|
with:
|
||||||
name: npm-package
|
name: npm-package
|
||||||
path: ./release-npm-package
|
path: ./release-npm-package
|
||||||
- run: brew unlink node@12
|
|
||||||
- run: brew install node
|
|
||||||
- run: ./ci/steps/release-packages.sh
|
- run: ./ci/steps/release-packages.sh
|
||||||
env:
|
env:
|
||||||
# Otherwise we get rate limited when fetching the ripgrep binary.
|
# Otherwise we get rate limited when fetching the ripgrep binary.
|
||||||
|
@ -118,7 +116,7 @@ jobs:
|
||||||
name: release-packages
|
name: release-packages
|
||||||
path: ./release-packages
|
path: ./release-packages
|
||||||
- name: Run ./ci/steps/build-docker-image.sh
|
- name: Run ./ci/steps/build-docker-image.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/build-docker-image.sh
|
args: ./ci/steps/build-docker-image.sh
|
||||||
- name: Upload release image
|
- name: Upload release image
|
||||||
|
@ -138,7 +136,7 @@ jobs:
|
||||||
name: release-packages
|
name: release-packages
|
||||||
path: ./release-packages
|
path: ./release-packages
|
||||||
- name: Run ./ci/steps/build-docker-image.sh
|
- name: Run ./ci/steps/build-docker-image.sh
|
||||||
uses: ./ci/container/arm64
|
uses: ./ci/images/centos7
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/build-docker-image.sh
|
args: ./ci/steps/build-docker-image.sh
|
||||||
- name: Upload release image
|
- name: Upload release image
|
||||||
|
|
|
@ -10,7 +10,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/publish-npm.sh
|
- name: Run ./ci/steps/publish-npm.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/publish-npm.sh
|
args: ./ci/steps/publish-npm.sh
|
||||||
env:
|
env:
|
||||||
|
@ -22,7 +22,7 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v1
|
- uses: actions/checkout@v1
|
||||||
- name: Run ./ci/steps/push-docker-manifest.sh
|
- name: Run ./ci/steps/push-docker-manifest.sh
|
||||||
uses: ./ci/container
|
uses: ./ci/images/debian8
|
||||||
with:
|
with:
|
||||||
args: ./ci/steps/push-docker-manifest.sh
|
args: ./ci/steps/push-docker-manifest.sh
|
||||||
env:
|
env:
|
||||||
|
|
|
@ -9,3 +9,4 @@ release-packages/
|
||||||
release-gcp/
|
release-gcp/
|
||||||
release-images/
|
release-images/
|
||||||
node_modules
|
node_modules
|
||||||
|
node-*
|
||||||
|
|
13
ci/README.md
13
ci/README.md
|
@ -35,12 +35,13 @@ Make sure you have `$GITHUB_TOKEN` set and [hub](https://github.com/github/hub)
|
||||||
10. Wait for the npm package to be published.
|
10. Wait for the npm package to be published.
|
||||||
11. Update the homebrew package.
|
11. Update the homebrew package.
|
||||||
- Send a pull request to [homebrew-core](https://github.com/Homebrew/homebrew-core) with the URL in the [formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/code-server.rb) updated.
|
- Send a pull request to [homebrew-core](https://github.com/Homebrew/homebrew-core) with the URL in the [formula](https://github.com/Homebrew/homebrew-core/blob/master/Formula/code-server.rb) updated.
|
||||||
|
12. Make sure to add a release without the `v` prefix for autoupdate from `3.2.0`.
|
||||||
|
|
||||||
## dev
|
## dev
|
||||||
|
|
||||||
This directory contains scripts used for the development of code-server.
|
This directory contains scripts used for the development of code-server.
|
||||||
|
|
||||||
- [./ci/dev/container](./dev/container)
|
- [./ci/dev/image](./dev/image)
|
||||||
- See [./doc/CONTRIBUTING.md](../doc/CONTRIBUTING.md) for docs on the development container.
|
- See [./doc/CONTRIBUTING.md](../doc/CONTRIBUTING.md) for docs on the development container.
|
||||||
- [./ci/dev/fmt.sh](./dev/fmt.sh) (`yarn fmt`)
|
- [./ci/dev/fmt.sh](./dev/fmt.sh) (`yarn fmt`)
|
||||||
- Runs formatters.
|
- Runs formatters.
|
||||||
|
@ -104,17 +105,17 @@ You can disable minification by setting `MINIFY=`.
|
||||||
- Post install script for the npm package.
|
- Post install script for the npm package.
|
||||||
- Bundled by`yarn release`.
|
- Bundled by`yarn release`.
|
||||||
|
|
||||||
## release-container
|
## release-image
|
||||||
|
|
||||||
This directory contains the release docker container.
|
This directory contains the release docker container image.
|
||||||
|
|
||||||
- [./release-container/build.sh](./release-container/build.sh)
|
- [./release-image/build.sh](./release-image/build.sh)
|
||||||
- Builds the release container with the tag `codercom/code-server-$ARCH:$VERSION`.
|
- Builds the release container with the tag `codercom/code-server-$ARCH:$VERSION`.
|
||||||
- Assumes debian releases are ready in `./release-packages`.
|
- Assumes debian releases are ready in `./release-packages`.
|
||||||
|
|
||||||
## container
|
## images
|
||||||
|
|
||||||
This directory contains the container for CI.
|
This directory contains the images for CI.
|
||||||
|
|
||||||
## steps
|
## steps
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,16 @@ release_archive() {
|
||||||
local release_name="code-server-$VERSION-$OS-$ARCH"
|
local release_name="code-server-$VERSION-$OS-$ARCH"
|
||||||
if [[ $OS == "linux" ]]; then
|
if [[ $OS == "linux" ]]; then
|
||||||
tar -czf "release-packages/$release_name.tar.gz" --transform "s/^\.\/release-standalone/$release_name/" ./release-standalone
|
tar -czf "release-packages/$release_name.tar.gz" --transform "s/^\.\/release-standalone/$release_name/" ./release-standalone
|
||||||
|
elif [[ $OS == "darwin" && $ARCH == "x86_64" ]]; then
|
||||||
|
# Just exists to make autoupdating from 3.2.0 work again.
|
||||||
|
mv ./release-standalone "./$release_name"
|
||||||
|
zip -r "release-packages/$release_name.zip" "./$release_name"
|
||||||
|
mv "./$release_name" ./release-standalone
|
||||||
|
return
|
||||||
else
|
else
|
||||||
tar -czf "release-packages/$release_name.tar.gz" -s "/^release-standalone/$release_name/" release-standalone
|
tar -czf "release-packages/$release_name.tar.gz" -s "/^release-standalone/$release_name/" release-standalone
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "done (release-packages/$release_name)"
|
echo "done (release-packages/$release_name)"
|
||||||
|
|
||||||
release_gcp
|
release_gcp
|
||||||
|
|
|
@ -17,14 +17,6 @@ main() {
|
||||||
mkdir -p "$RELEASE_PATH/bin"
|
mkdir -p "$RELEASE_PATH/bin"
|
||||||
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
|
rsync ./ci/build/code-server.sh "$RELEASE_PATH/bin/code-server"
|
||||||
rsync "$node_path" "$RELEASE_PATH/lib/node"
|
rsync "$node_path" "$RELEASE_PATH/lib/node"
|
||||||
if [[ $OS == "linux" ]]; then
|
|
||||||
bundle_dynamic_lib libstdc++
|
|
||||||
bundle_dynamic_lib libgcc_s
|
|
||||||
elif [[ $OS == "macos" ]]; then
|
|
||||||
bundle_dynamic_lib libicui18n
|
|
||||||
bundle_dynamic_lib libicuuc
|
|
||||||
bundle_dynamic_lib libicudata
|
|
||||||
fi
|
|
||||||
|
|
||||||
ln -s "./bin/code-server" "$RELEASE_PATH/code-server"
|
ln -s "./bin/code-server" "$RELEASE_PATH/code-server"
|
||||||
ln -s "./lib/node" "$RELEASE_PATH/node"
|
ln -s "./lib/node" "$RELEASE_PATH/node"
|
||||||
|
@ -33,17 +25,4 @@ main() {
|
||||||
yarn --production --frozen-lockfile
|
yarn --production --frozen-lockfile
|
||||||
}
|
}
|
||||||
|
|
||||||
bundle_dynamic_lib() {
|
|
||||||
local lib_name="$1"
|
|
||||||
local lib_path
|
|
||||||
|
|
||||||
if [[ $OS == "linux" ]]; then
|
|
||||||
lib_path="$(ldd "$RELEASE_PATH/lib/node" | grep "$lib_name" | awk '{print $3 }')"
|
|
||||||
elif [[ $OS == "macos" ]]; then
|
|
||||||
lib_path="$(otool -L "$RELEASE_PATH/lib/node" | grep "$lib_name" | awk '{print $1 }')"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cp "$lib_path" "$RELEASE_PATH/lib"
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
||||||
|
|
|
@ -1,25 +1,36 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
# This script is intended to be bundled into the standalone releases.
|
# This script is intended to be bundled into the standalone releases.
|
||||||
# Runs code-server with the bundled node binary.
|
# Runs code-server with the bundled node binary.
|
||||||
|
|
||||||
# More complicated than readlink -f or realpath to support macOS.
|
_realpath() {
|
||||||
# See https://github.com/cdr/code-server/issues/1537
|
# See https://github.com/cdr/code-server/issues/1537 on why no realpath or readlink -f.
|
||||||
bin_dir() {
|
|
||||||
# We read the symlink, which may be relative from $0.
|
script="$1"
|
||||||
dst="$(readlink "$0")"
|
cd "$(dirname "$script")"
|
||||||
# We cd into the $0 directory.
|
|
||||||
cd "$(dirname "$0")" || exit 1
|
while [ -L "$(basename "$script")" ]; do
|
||||||
# Now we can cd into the dst directory.
|
if [ -L "./node" ] && [ -L "./code-server" ] &&
|
||||||
cd "$(dirname "$dst")" || exit 1
|
[ -f "package.json" ] &&
|
||||||
# Finally we use pwd -P to print the absolute path of the directory of $dst.
|
cat package.json | grep -q '^ "name": "code-server",$'; then
|
||||||
pwd -P || exit 1
|
echo "***** Please use the script in bin/code-server instead!" >&2
|
||||||
|
echo "***** This script will soon be removed!" >&2
|
||||||
|
echo "***** See the release notes at https://github.com/cdr/code-server/releases/tag/v3.4.0" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
|
script="$(readlink "$(basename "$script")")"
|
||||||
|
cd "$(dirname "$script")"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$PWD/$(basename "$script")"
|
||||||
}
|
}
|
||||||
|
|
||||||
BIN_DIR=$(bin_dir)
|
root() {
|
||||||
if [ "$(uname)" = "Linux" ]; then
|
script="$(_realpath "$0")"
|
||||||
export LD_LIBRARY_PATH="$BIN_DIR/../lib${LD_LIBRARY_PATH+:$LD_LIBRARY_PATH}"
|
bin_dir="$(dirname "$script")"
|
||||||
elif [ "$(uname)" = "Darwin" ]; then
|
dirname "$bin_dir"
|
||||||
export DYLD_LIBRARY_PATH="$BIN_DIR/../lib${DYLD_LIBRARY_PATH+:$DYLD_LIBRARY_PATH}"
|
}
|
||||||
fi
|
|
||||||
exec "$BIN_DIR/../lib/node" "$BIN_DIR/.." "$@"
|
ROOT="$(root)"
|
||||||
|
exec "$ROOT/lib/node" "$ROOT" "$@"
|
||||||
|
|
|
@ -15,7 +15,8 @@ main() {
|
||||||
./release-standalone/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --install-extension ms-python.python
|
./release-standalone/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --install-extension ms-python.python
|
||||||
local installed_extensions
|
local installed_extensions
|
||||||
installed_extensions="$(./release-standalone/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --list-extensions 2>&1)"
|
installed_extensions="$(./release-standalone/bin/code-server --extensions-dir "$EXTENSIONS_DIR" --list-extensions 2>&1)"
|
||||||
if [[ $installed_extensions != "ms-python.python" ]]; then
|
if [[ $installed_extensions != "info Using config file ~/.config/code-server/config.yaml
|
||||||
|
ms-python.python" ]]; then
|
||||||
echo "Unexpected output from listing extensions:"
|
echo "Unexpected output from listing extensions:"
|
||||||
echo "$installed_extensions"
|
echo "$installed_extensions"
|
||||||
exit 1
|
exit 1
|
||||||
|
|
|
@ -1,53 +0,0 @@
|
||||||
FROM debian:9
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
|
|
||||||
# Needed for debian repositories added below.
|
|
||||||
RUN apt-get install -y curl gnupg
|
|
||||||
|
|
||||||
# Installs node.
|
|
||||||
RUN curl -fsSL https://deb.nodesource.com/setup_14.x | bash - && \
|
|
||||||
apt-get install -y nodejs
|
|
||||||
|
|
||||||
# Installs yarn.
|
|
||||||
RUN curl -fsSL https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \
|
|
||||||
echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \
|
|
||||||
apt-get update && apt-get install -y yarn
|
|
||||||
|
|
||||||
# Installs VS Code build deps.
|
|
||||||
RUN apt-get install -y build-essential \
|
|
||||||
libsecret-1-dev \
|
|
||||||
libx11-dev \
|
|
||||||
libxkbfile-dev
|
|
||||||
|
|
||||||
# Installs envsubst.
|
|
||||||
RUN apt-get install -y gettext-base
|
|
||||||
|
|
||||||
# Misc build dependencies.
|
|
||||||
RUN apt-get install -y git rsync unzip
|
|
||||||
|
|
||||||
# We need latest jq from debian buster for date support.
|
|
||||||
RUN ARCH="$(dpkg --print-architecture)" && \
|
|
||||||
curl -fsSOL http://http.us.debian.org/debian/pool/main/libo/libonig/libonig5_6.9.1-1_$ARCH.deb && \
|
|
||||||
dpkg -i libonig*.deb && \
|
|
||||||
curl -fsSOL http://http.us.debian.org/debian/pool/main/j/jq/libjq1_1.5+dfsg-2+b1_$ARCH.deb && \
|
|
||||||
dpkg -i libjq*.deb && \
|
|
||||||
curl -fsSOL http://http.us.debian.org/debian/pool/main/j/jq/jq_1.5+dfsg-2+b1_$ARCH.deb && \
|
|
||||||
dpkg -i jq*.deb && rm *.deb
|
|
||||||
|
|
||||||
# Installs shellcheck.
|
|
||||||
# Unfortunately coredumps on debian:8 so disabled for now.
|
|
||||||
#RUN curl -fsSL https://github.com/koalaman/shellcheck/releases/download/v0.7.1/shellcheck-v0.7.1.linux.$(uname -m).tar.xz | \
|
|
||||||
# tar -xJ && \
|
|
||||||
# mv shellcheck*/shellcheck /usr/local/bin && \
|
|
||||||
# rm -R shellcheck*
|
|
||||||
|
|
||||||
# Install Go dependencies
|
|
||||||
RUN ARCH="$(dpkg --print-architecture)" && \
|
|
||||||
curl -fsSL "https://dl.google.com/go/go1.14.3.linux-$ARCH.tar.gz" | tar -C /usr/local -xz
|
|
||||||
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH
|
|
||||||
ENV GO111MODULE=on
|
|
||||||
RUN go get mvdan.cc/sh/v3/cmd/shfmt
|
|
||||||
RUN go get github.com/goreleaser/nfpm/cmd/nfpm
|
|
||||||
|
|
||||||
RUN curl -fsSL https://get.docker.com | sh
|
|
|
@ -1,6 +0,0 @@
|
||||||
# arm64
|
|
||||||
|
|
||||||
Unfortunately there is no arm64 build of `debian:8` so
|
|
||||||
we need to use `debian:9` instead.
|
|
||||||
|
|
||||||
This is just an exact copy of [../Dockerfile](../Dockerfile) with the base image change.
|
|
|
@ -4,7 +4,7 @@ set -euo pipefail
|
||||||
main() {
|
main() {
|
||||||
cd "$(dirname "$0")/../.."
|
cd "$(dirname "$0")/../.."
|
||||||
|
|
||||||
shfmt -i 2 -w -s -sr $(git ls-files "*.sh")
|
shfmt -i 2 -w -sr $(git ls-files "*.sh")
|
||||||
|
|
||||||
local prettierExts
|
local prettierExts
|
||||||
prettierExts=(
|
prettierExts=(
|
||||||
|
@ -24,6 +24,8 @@ main() {
|
||||||
doctoc --title '# FAQ' doc/FAQ.md > /dev/null
|
doctoc --title '# FAQ' doc/FAQ.md > /dev/null
|
||||||
doctoc --title '# Setup Guide' doc/guide.md > /dev/null
|
doctoc --title '# Setup Guide' doc/guide.md > /dev/null
|
||||||
doctoc --title '# Install' doc/install.md > /dev/null
|
doctoc --title '# Install' doc/install.md > /dev/null
|
||||||
|
doctoc --title '# npm Install Requirements' doc/npm.md > /dev/null
|
||||||
|
doctoc --title '# Contributing' doc/CONTRIBUTING.md > /dev/null
|
||||||
|
|
||||||
if [[ ${CI-} && $(git ls-files --other --modified --exclude-standard) ]]; then
|
if [[ ${CI-} && $(git ls-files --other --modified --exclude-standard) ]]; then
|
||||||
echo "Files need generation or are formatted incorrectly:"
|
echo "Files need generation or are formatted incorrectly:"
|
||||||
|
|
|
@ -42,7 +42,7 @@ run() {
|
||||||
|
|
||||||
build() {
|
build() {
|
||||||
echo "--- Building $container_name"
|
echo "--- Building $container_name"
|
||||||
docker build -t $container_name ./ci/dev/container > /dev/null
|
docker build -t $container_name ./ci/dev/image > /dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
|
@ -7,9 +7,9 @@ main() {
|
||||||
eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js")
|
eslint --max-warnings=0 --fix $(git ls-files "*.ts" "*.tsx" "*.js")
|
||||||
stylelint $(git ls-files "*.css")
|
stylelint $(git ls-files "*.css")
|
||||||
tsc --noEmit
|
tsc --noEmit
|
||||||
# See comment in ./ci/container/Dockerfile
|
# See comment in ./ci/image/debian8
|
||||||
if [[ ! ${CI-} ]]; then
|
if [[ ! ${CI-} ]]; then
|
||||||
shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090 $(git ls-files "*.sh")
|
shellcheck -e SC2046,SC2164,SC2154,SC1091,SC1090,SC2002 $(git ls-files "*.sh")
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
FROM centos:7
|
||||||
|
|
||||||
|
RUN ARCH="$(uname -m | sed 's/86_64/64/; s/aarch64/arm64/')" && \
|
||||||
|
curl -fsSL "https://nodejs.org/dist/v14.4.0/node-v14.4.0-linux-$ARCH.tar.xz" | tar -C /usr/local -xJ && \
|
||||||
|
mv /usr/local/node-v14.4.0-linux-$ARCH /usr/local/node-v14.4.0
|
||||||
|
ENV PATH=/usr/local/node-v14.4.0/bin:$PATH
|
||||||
|
RUN npm install -g yarn
|
||||||
|
|
||||||
|
RUN yum groupinstall -y 'Development Tools'
|
||||||
|
RUN yum install -y python2 libsecret-devel libX11-devel libxkbfile-devel
|
||||||
|
|
||||||
|
RUN npm config set python python2
|
||||||
|
|
||||||
|
RUN yum install -y epel-release && yum install -y jq
|
||||||
|
RUN yum install -y rsync
|
||||||
|
|
||||||
|
# Copied from ../debian8/Dockerfile
|
||||||
|
# Install Go dependencies
|
||||||
|
RUN ARCH="$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')" && \
|
||||||
|
curl -fsSL "https://dl.google.com/go/go1.14.3.linux-$ARCH.tar.gz" | tar -C /usr/local -xz
|
||||||
|
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH
|
||||||
|
ENV GO111MODULE=on
|
||||||
|
RUN go get mvdan.cc/sh/v3/cmd/shfmt
|
||||||
|
RUN go get github.com/goreleaser/nfpm/cmd/nfpm
|
||||||
|
|
||||||
|
RUN curl -fsSL https://get.docker.com | sh
|
|
@ -43,7 +43,7 @@ RUN ARCH="$(dpkg --print-architecture)" && \
|
||||||
# rm -R shellcheck*
|
# rm -R shellcheck*
|
||||||
|
|
||||||
# Install Go dependencies
|
# Install Go dependencies
|
||||||
RUN ARCH="$(dpkg --print-architecture)" && \
|
RUN ARCH="$(uname -m | sed 's/x86_64/amd64/; s/aarch64/arm64/')" && \
|
||||||
curl -fsSL "https://dl.google.com/go/go1.14.3.linux-$ARCH.tar.gz" | tar -C /usr/local -xz
|
curl -fsSL "https://dl.google.com/go/go1.14.3.linux-$ARCH.tar.gz" | tar -C /usr/local -xz
|
||||||
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH
|
ENV PATH=/usr/local/go/bin:/root/go/bin:$PATH
|
||||||
ENV GO111MODULE=on
|
ENV GO111MODULE=on
|
|
@ -5,7 +5,7 @@ main() {
|
||||||
cd "$(dirname "$0")/../.."
|
cd "$(dirname "$0")/../.."
|
||||||
source ./ci/lib.sh
|
source ./ci/lib.sh
|
||||||
|
|
||||||
docker build -t "codercom/code-server-$ARCH:$VERSION" -f ./ci/release-container/Dockerfile .
|
docker build -t "codercom/code-server-$ARCH:$VERSION" -f ./ci/release-image/Dockerfile .
|
||||||
}
|
}
|
||||||
|
|
||||||
main "$@"
|
main "$@"
|
|
@ -5,7 +5,7 @@ main() {
|
||||||
cd "$(dirname "$0")/../.."
|
cd "$(dirname "$0")/../.."
|
||||||
source ./ci/lib.sh
|
source ./ci/lib.sh
|
||||||
|
|
||||||
./ci/release-container/build.sh
|
./ci/release-image/build.sh
|
||||||
|
|
||||||
mkdir -p release-images
|
mkdir -p release-images
|
||||||
docker save "codercom/code-server-$ARCH:$VERSION" > "release-images/code-server-$ARCH-$VERSION.tar"
|
docker save "codercom/code-server-$ARCH:$VERSION" > "release-images/code-server-$ARCH-$VERSION.tar"
|
||||||
|
|
|
@ -4,6 +4,11 @@ set -euo pipefail
|
||||||
main() {
|
main() {
|
||||||
cd "$(dirname "$0")/../.."
|
cd "$(dirname "$0")/../.."
|
||||||
|
|
||||||
|
if [[ $OSTYPE == darwin* ]]; then
|
||||||
|
curl -L https://nodejs.org/dist/v14.4.0/node-v14.4.0-darwin-x64.tar.gz | tar -xz
|
||||||
|
PATH="$PATH:node-v14.4.0-darwin-x64/bin"
|
||||||
|
fi
|
||||||
|
|
||||||
# https://github.com/actions/upload-artifact/issues/38
|
# https://github.com/actions/upload-artifact/issues/38
|
||||||
tar -xzf release-npm-package/package.tar.gz
|
tar -xzf release-npm-package/package.tar.gz
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,15 @@
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
# Contributing
|
# Contributing
|
||||||
|
|
||||||
|
- [Requirements](#requirements)
|
||||||
|
- [Development Workflow](#development-workflow)
|
||||||
|
- [Build](#build)
|
||||||
|
- [Structure](#structure)
|
||||||
|
- [VS Code Patch](#vs-code-patch)
|
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
- [Detailed CI and build process docs](../ci)
|
- [Detailed CI and build process docs](../ci)
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
@ -11,7 +21,7 @@ Differences:
|
||||||
- We require a minimum of node v12 but later versions should work.
|
- We require a minimum of node v12 but later versions should work.
|
||||||
- We use [fnpm](https://github.com/goreleaser/nfpm) to build `.deb` and `.rpm` packages.
|
- We use [fnpm](https://github.com/goreleaser/nfpm) to build `.deb` and `.rpm` packages.
|
||||||
- We use [jq](https://stedolan.github.io/jq/) to build code-server releases.
|
- We use [jq](https://stedolan.github.io/jq/) to build code-server releases.
|
||||||
- The [CI container](../ci/container/Dockerfile) is a useful reference for all our dependencies.
|
- The [CI container](../ci/images/debian8/Dockerfile) is a useful reference for all our dependencies.
|
||||||
|
|
||||||
## Development Workflow
|
## Development Workflow
|
||||||
|
|
||||||
|
@ -25,7 +35,7 @@ yarn watch
|
||||||
To develop inside of an isolated docker container:
|
To develop inside of an isolated docker container:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
./ci/dev/container/exec.sh
|
./ci/dev/image/exec.sh
|
||||||
|
|
||||||
root@12345:/code-server# yarn
|
root@12345:/code-server# yarn
|
||||||
root@12345:/code-server# yarn vscode
|
root@12345:/code-server# yarn vscode
|
||||||
|
|
|
@ -47,14 +47,15 @@ However, it is not entirely equivalent to Microsoft's VS Code.
|
||||||
|
|
||||||
While the core of VS Code is open source, the marketplace and many published Microsoft extensions are not.
|
While the core of VS Code is open source, the marketplace and many published Microsoft extensions are not.
|
||||||
|
|
||||||
Not only are they closed source, Microsoft prohibits the use of any non-Microsoft VS Code from accessing their marketplace.
|
Furthermore, Microsoft prohibits the use of any non-Microsoft VS Code from accessing their marketplace.
|
||||||
|
|
||||||
See the [TOS](https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf).
|
See the [TOS](https://cdn.vsassets.io/v/M146_20190123.39/_content/Microsoft-Visual-Studio-Marketplace-Terms-of-Use.pdf).
|
||||||
|
|
||||||
> Marketplace Offerings are intended for use only with Visual Studio Products and Services
|
> Marketplace Offerings are intended for use only with Visual Studio Products and Services
|
||||||
> and you may only install and use Marketplace Offerings with Visual Studio Products and Services.
|
> and you may only install and use Marketplace Offerings with Visual Studio Products and Services.
|
||||||
|
|
||||||
As a result, we have created our own marketplace for open source extensions.
|
As a result, we cannot offer any extensions on the Microsoft marketplace. Instead,
|
||||||
|
we have created our own marketplace for open source extensions.
|
||||||
It works by scraping GitHub for VS Code extensions and building them. It's not perfect but getting
|
It works by scraping GitHub for VS Code extensions and building them. It's not perfect but getting
|
||||||
better by the day with more and more extensions.
|
better by the day with more and more extensions.
|
||||||
|
|
||||||
|
|
10
doc/npm.md
10
doc/npm.md
|
@ -1,5 +1,13 @@
|
||||||
|
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
||||||
# npm Install Requirements
|
# npm Install Requirements
|
||||||
|
|
||||||
|
- [Ubuntu, Debian](#ubuntu-debian)
|
||||||
|
- [Fedora, CentOS, RHEL](#fedora-centos-rhel)
|
||||||
|
- [macOS](#macos)
|
||||||
|
|
||||||
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
||||||
|
|
||||||
If you're installing the npm module you'll need certain dependencies to build
|
If you're installing the npm module you'll need certain dependencies to build
|
||||||
the native modules used by VS Code.
|
the native modules used by VS Code.
|
||||||
|
|
||||||
|
@ -20,7 +28,7 @@ sudo apt-get install -y \
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
sudo yum groupinstall -y 'Development Tools'
|
sudo yum groupinstall -y 'Development Tools'
|
||||||
sudo yum config-manager --set-enabled PowerTools
|
sudo yum config-manager --set-enabled PowerTools # unnecessary on CentOS 7
|
||||||
sudo yum install -y python2 libsecret-devel libX11-devel libxkbfile-devel
|
sudo yum install -y python2 libsecret-devel libX11-devel libxkbfile-devel
|
||||||
npm config set python python2
|
npm config set python python2
|
||||||
```
|
```
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
},
|
},
|
||||||
"main": "out/node/entry.js",
|
"main": "out/node/entry.js",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/adm-zip": "^0.4.32",
|
|
||||||
"@types/fs-extra": "^8.0.1",
|
"@types/fs-extra": "^8.0.1",
|
||||||
"@types/http-proxy": "^1.17.4",
|
"@types/http-proxy": "^1.17.4",
|
||||||
"@types/js-yaml": "^3.12.3",
|
"@types/js-yaml": "^3.12.3",
|
||||||
|
@ -66,7 +65,6 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@coder/logger": "1.1.11",
|
"@coder/logger": "1.1.11",
|
||||||
"adm-zip": "^0.4.14",
|
|
||||||
"env-paths": "^2.2.0",
|
"env-paths": "^2.2.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
"http-proxy": "^1.18.0",
|
"http-proxy": "^1.18.0",
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { field, logger } from "@coder/logger"
|
import { field, logger } from "@coder/logger"
|
||||||
import zip from "adm-zip"
|
|
||||||
import * as cp from "child_process"
|
import * as cp from "child_process"
|
||||||
import * as fs from "fs-extra"
|
import * as fs from "fs-extra"
|
||||||
import * as http from "http"
|
import * as http from "http"
|
||||||
|
@ -213,11 +212,7 @@ export class UpdateHttpProvider extends HttpProvider {
|
||||||
const response = await this.requestResponse(url)
|
const response = await this.requestResponse(url)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (downloadPath.endsWith(".tar.gz")) {
|
downloadPath = await this.extractTar(response, downloadPath)
|
||||||
downloadPath = await this.extractTar(response, downloadPath)
|
|
||||||
} else {
|
|
||||||
downloadPath = await this.extractZip(response, downloadPath)
|
|
||||||
}
|
|
||||||
logger.debug("Downloaded update", field("path", downloadPath))
|
logger.debug("Downloaded update", field("path", downloadPath))
|
||||||
|
|
||||||
// The archive should have a directory inside at the top level with the
|
// The archive should have a directory inside at the top level with the
|
||||||
|
@ -275,40 +270,6 @@ export class UpdateHttpProvider extends HttpProvider {
|
||||||
return downloadPath
|
return downloadPath
|
||||||
}
|
}
|
||||||
|
|
||||||
private async extractZip(response: Readable, downloadPath: string): Promise<string> {
|
|
||||||
logger.debug("Downloading zip", field("path", downloadPath))
|
|
||||||
|
|
||||||
response.pause()
|
|
||||||
await fs.remove(downloadPath)
|
|
||||||
|
|
||||||
const write = fs.createWriteStream(downloadPath)
|
|
||||||
response.pipe(write)
|
|
||||||
response.on("error", (error) => write.destroy(error))
|
|
||||||
response.on("close", () => write.end())
|
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
write.on("error", reject)
|
|
||||||
write.on("close", resolve)
|
|
||||||
response.resume
|
|
||||||
})
|
|
||||||
|
|
||||||
const zipPath = downloadPath
|
|
||||||
downloadPath = downloadPath.replace(/\.zip$/, "")
|
|
||||||
await fs.remove(downloadPath)
|
|
||||||
|
|
||||||
logger.debug("Extracting zip", field("path", zipPath))
|
|
||||||
|
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
new zip(zipPath).extractAllToAsync(downloadPath, true, (error) => {
|
|
||||||
return error ? reject(error) : resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
await fs.remove(zipPath)
|
|
||||||
|
|
||||||
return downloadPath
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an update return the name for the packaged archived.
|
* Given an update return the name for the packaged archived.
|
||||||
*/
|
*/
|
||||||
|
@ -329,7 +290,7 @@ export class UpdateHttpProvider extends HttpProvider {
|
||||||
if (arch === "x64") {
|
if (arch === "x64") {
|
||||||
arch = "x86_64"
|
arch = "x86_64"
|
||||||
}
|
}
|
||||||
return `code-server-${update.version}-${target}-${arch}.${target === "darwin" ? "zip" : "tar.gz"}`
|
return `code-server-${update.version}-${target}-${arch}.tar.gz`
|
||||||
}
|
}
|
||||||
|
|
||||||
private async request(uri: string): Promise<Buffer> {
|
private async request(uri: string): Promise<Buffer> {
|
||||||
|
|
|
@ -348,7 +348,9 @@ export async function readConfigFile(configPath?: string): Promise<Args> {
|
||||||
logger.info(`Wrote default config file to ${humanPath(configPath)}`)
|
logger.info(`Wrote default config file to ${humanPath(configPath)}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info(`Using config file ${humanPath(configPath)}`)
|
if (!process.env.CODE_SERVER_PARENT_PID) {
|
||||||
|
logger.info(`Using config file ${humanPath(configPath)}`)
|
||||||
|
}
|
||||||
|
|
||||||
const configFile = await fs.readFile(configPath)
|
const configFile = await fs.readFile(configPath)
|
||||||
const config = yaml.safeLoad(configFile.toString(), {
|
const config = yaml.safeLoad(configFile.toString(), {
|
||||||
|
|
|
@ -31,11 +31,7 @@ try {
|
||||||
const version = pkg.version || "development"
|
const version = pkg.version || "development"
|
||||||
const commit = pkg.commit || "development"
|
const commit = pkg.commit || "development"
|
||||||
|
|
||||||
const main = async (cliArgs: Args): Promise<void> => {
|
const main = async (args: Args, cliArgs: Args, configArgs: Args): Promise<void> => {
|
||||||
const configArgs = await readConfigFile(cliArgs.config)
|
|
||||||
// This prioritizes the flags set in args over the ones in the config file.
|
|
||||||
let args = Object.assign(configArgs, cliArgs)
|
|
||||||
|
|
||||||
if (!args.auth) {
|
if (!args.auth) {
|
||||||
args = {
|
args = {
|
||||||
...args,
|
...args,
|
||||||
|
@ -127,18 +123,21 @@ const main = async (cliArgs: Args): Promise<void> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function entry(): Promise<void> {
|
async function entry(): Promise<void> {
|
||||||
const tryParse = async (): Promise<Args> => {
|
const tryParse = async (): Promise<[Args, Args, Args]> => {
|
||||||
try {
|
try {
|
||||||
let args = parse(process.argv.slice(2))
|
const cliArgs = parse(process.argv.slice(2))
|
||||||
|
const configArgs = await readConfigFile(cliArgs.config)
|
||||||
|
// This prioritizes the flags set in args over the ones in the config file.
|
||||||
|
let args = Object.assign(configArgs, cliArgs)
|
||||||
args = await setDefaults(args)
|
args = await setDefaults(args)
|
||||||
return args
|
return [args, cliArgs, configArgs]
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error.message)
|
console.error(error.message)
|
||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const args = await tryParse()
|
const [args, cliArgs, configArgs] = await tryParse()
|
||||||
if (args.help) {
|
if (args.help) {
|
||||||
console.log("code-server", version, commit)
|
console.log("code-server", version, commit)
|
||||||
console.log("")
|
console.log("")
|
||||||
|
@ -182,7 +181,7 @@ async function entry(): Promise<void> {
|
||||||
})
|
})
|
||||||
vscode.on("exit", (code) => process.exit(code || 0))
|
vscode.on("exit", (code) => process.exit(code || 0))
|
||||||
} else {
|
} else {
|
||||||
wrap(() => main(args))
|
wrap(() => main(args, cliArgs, configArgs))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import zip from "adm-zip"
|
|
||||||
import * as assert from "assert"
|
import * as assert from "assert"
|
||||||
import * as fs from "fs-extra"
|
import * as fs from "fs-extra"
|
||||||
import * as http from "http"
|
import * as http from "http"
|
||||||
import * as os from "os"
|
|
||||||
import * as path from "path"
|
import * as path from "path"
|
||||||
import * as tar from "tar-fs"
|
import * as tar from "tar-fs"
|
||||||
import * as zlib from "zlib"
|
import * as zlib from "zlib"
|
||||||
|
@ -88,28 +86,18 @@ describe("update", () => {
|
||||||
fs.writeFile(path.join(archivePath, archiveName, "node"), `NODE BINARY`),
|
fs.writeFile(path.join(archivePath, archiveName, "node"), `NODE BINARY`),
|
||||||
])
|
])
|
||||||
|
|
||||||
if (os.platform() === "darwin") {
|
await new Promise((resolve, reject) => {
|
||||||
await new Promise((resolve, reject) => {
|
const write = fs.createWriteStream(archivePath + ".tar.gz")
|
||||||
const zipFile = new zip()
|
const compress = zlib.createGzip()
|
||||||
zipFile.addLocalFolder(archivePath)
|
compress.pipe(write)
|
||||||
zipFile.writeZip(archivePath + ".zip", (error) => {
|
compress.on("error", (error) => compress.destroy(error))
|
||||||
return error ? reject(error) : resolve(error)
|
compress.on("close", () => write.end())
|
||||||
})
|
tar.pack(archivePath).pipe(compress)
|
||||||
|
write.on("close", reject)
|
||||||
|
write.on("finish", () => {
|
||||||
|
resolve()
|
||||||
})
|
})
|
||||||
} else {
|
})
|
||||||
await new Promise((resolve, reject) => {
|
|
||||||
const write = fs.createWriteStream(archivePath + ".tar.gz")
|
|
||||||
const compress = zlib.createGzip()
|
|
||||||
compress.pipe(write)
|
|
||||||
compress.on("error", (error) => compress.destroy(error))
|
|
||||||
compress.on("close", () => write.end())
|
|
||||||
tar.pack(archivePath).pipe(compress)
|
|
||||||
write.on("close", reject)
|
|
||||||
write.on("finish", () => {
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
after(() => {
|
after(() => {
|
||||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -910,13 +910,6 @@
|
||||||
traverse "^0.6.6"
|
traverse "^0.6.6"
|
||||||
unified "^6.1.6"
|
unified "^6.1.6"
|
||||||
|
|
||||||
"@types/adm-zip@^0.4.32":
|
|
||||||
version "0.4.33"
|
|
||||||
resolved "https://registry.yarnpkg.com/@types/adm-zip/-/adm-zip-0.4.33.tgz#ea5b94f771443f655613b64f920c0555867200dd"
|
|
||||||
integrity sha512-WM0DCWFLjXtddl0fu0+iN2ZF+qz8RF9RddG5OSy/S90AQz01Fu8lHn/3oTIZDxvG8gVcnBLAHMHOdBLbV6m6Mw==
|
|
||||||
dependencies:
|
|
||||||
"@types/node" "*"
|
|
||||||
|
|
||||||
"@types/color-name@^1.1.1":
|
"@types/color-name@^1.1.1":
|
||||||
version "1.1.1"
|
version "1.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
|
||||||
|
@ -1130,11 +1123,6 @@ acorn@^7.1.1:
|
||||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
|
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf"
|
||||||
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
|
integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==
|
||||||
|
|
||||||
adm-zip@^0.4.14:
|
|
||||||
version "0.4.14"
|
|
||||||
resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.14.tgz#2cf312bcc9f8875df835b0f6040bd89be0a727a9"
|
|
||||||
integrity sha512-/9aQCnQHF+0IiCl0qhXoK7qs//SwYE7zX8lsr/DNk1BRAHYxeLZPL4pguwK29gUEqasYQjqPtEpDRSWEkdHn9g==
|
|
||||||
|
|
||||||
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
||||||
version "6.12.2"
|
version "6.12.2"
|
||||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
|
||||||
|
|
Loading…
Reference in New Issue