diff --git a/README.md b/README.md
index 2bb844ccf..36e20ec24 100644
--- a/README.md
+++ b/README.md
@@ -98,14 +98,24 @@ curl -fsSL https://d2lang.com/install.sh | sh -s --
You can run the install script with `--dry-run` to see the commands that will be used
to install without executing them.
-To uninstall:
+Or if you have Go installed you can install from source though you won't get the manpage:
+
+```sh
+go install oss.terrastruct.com/d2@latest
+```
+
+To uninstall with the install script:
```sh
curl -fsSL https://d2lang.com/install.sh | sh -s -- --uninstall
```
-For detailed installation docs, with alternative methods and examples for each OS, see
-[./docs/INSTALL.md](./docs/INSTALL.md).
+For detailed installation docs, see [./docs/INSTALL.md](./docs/INSTALL.md).
+We demonstrate alternative methods and examples for each OS.
+
+As well, the functioning of the install script is described in detail to alleviate any
+concern of its use. We recommend using your OS's package manager directly instead for
+improved security but the install script is by no means insecure.
## D2 as a library
diff --git a/ci/fmt.sh b/ci/fmt.sh
index 75c1f1924..4fb39da34 100755
--- a/ci/fmt.sh
+++ b/ci/fmt.sh
@@ -6,4 +6,7 @@ cd -- "$(dirname "$0")/.."
if is_changed README.md; then
sh_c tocsubst --skip 1 README.md
fi
+if is_changed docs/INSTALL.md; then
+ sh_c tocsubst --skip 1 docs/INSTALL.md
+fi
./ci/sub/fmt/make.sh
diff --git a/ci/release/_install.sh b/ci/release/_install.sh
index 49f936ffc..510a9c52d 100755
--- a/ci/release/_install.sh
+++ b/ci/release/_install.sh
@@ -91,6 +91,9 @@ note: Deleting the unarchived releases will cause --uninstall to stop working.
You can rerun install.sh to update your version of D2. install.sh will avoid reinstalling
if the installed version is the latest unless --force is passed.
+
+See https://github.com/terrastruct/d2/blob/master/docs/INSTALL.md#security for
+documentation on its security.
EOF
}
@@ -506,4 +509,7 @@ brew() {
HOMEBREW_NO_INSTALL_CLEANUP=1 HOMEBREW_NO_AUTO_UPDATE=1 command brew "$@"
}
+# The main function does more than provide organization. It provides robustness in that if
+# the install script was to only partial download into sh, sh will not execute it because
+# main is not invoked until the very last byte.
main "$@"
diff --git a/ci/release/changelogs/next.md b/ci/release/changelogs/next.md
index 4c6e6f979..6446165c6 100644
--- a/ci/release/changelogs/next.md
+++ b/ci/release/changelogs/next.md
@@ -1,4 +1,4 @@
-#### Features ๐
+#### Features ๐ธ
- Formatting of d2 scripts is supported on the CLI with the `fmt` subcommand.
[#292](https://github.com/terrastruct/d2/pull/292)
@@ -17,7 +17,7 @@
- `-b/--bundle` flag to `d2` now works and bundles all image assets directly as base64
data urls. [#278](https://github.com/terrastruct/d2/pull/278)
-#### Improvements ๐ง
+#### Improvements ๐งน
- Local images can now be included, e.g. `icon: ./my_img.png`.
[#146](https://github.com/terrastruct/d2/issues/146)
@@ -32,7 +32,7 @@
- `BROWSER=0` now works to disable opening a browser on `--watch`.
[#311](https://github.com/terrastruct/d2/pull/311)
-#### Bugfixes ๐ด
+#### Bugfixes โ๏ธ
- 3D style was missing border and other styles for its top and right faces.
[#187](https://github.com/terrastruct/d2/pull/187)
diff --git a/ci/release/changelogs/template.md b/ci/release/changelogs/template.md
index dd3f64b05..131061b70 100644
--- a/ci/release/changelogs/template.md
+++ b/ci/release/changelogs/template.md
@@ -1,5 +1,5 @@
-#### Features ๐
+#### Features ๐ธ
-#### Improvements ๐ง
+#### Improvements ๐งน
-#### Bugfixes ๐ด
+#### Bugfixes โ๏ธ
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 95d677851..97ec69d1b 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -1,15 +1,16 @@
# install
-You may install D2 through any of the following methods.
+You may install `d2` through any of the following methods.
-
-- [install.sh](#installsh)
-- [macOS (Homebrew)](#macos-homebrew)
-- [Standalone](#standalone)
-- [From source](#from-source)
-
-
+- install.sh
+ - Security
+- macOS (Homebrew)
+- Standalone
+ - Manual
+ - PREFIX
+- From source
+- Coming soon
## install.sh
@@ -31,6 +32,36 @@ methods:
curl -fsSL https://d2lang.com/install.sh | sh -s -- --help
```
+### Security
+
+The install script is not the most secure way to install d2. We recommend that if
+possible, you use your OS's package manager directly or install from source with `go` as
+described below.
+
+But this does not mean the install script is insecure. There is no major flaw that
+the install script is more vulnerable to than any other method of manual installation.
+The most secure installation method involves a second independent entity, i.e your OS
+package repos or Go's proxy server.
+
+We're careful shell programmers and are aware of the many footguns of the Unix shell. Our
+script was written carefully and with detail. For example, it is not vulnerable to partial
+execution and the entire script runs with `set -eu` and very meticulous quoting.
+
+It follows the XDG standards, installs `d2` properly into a Unix hierarchy path (defaulting
+to /usr/local though you can use ~/.local to avoid sudo if you'd like) and allows for easy
+uninstall.
+
+Some other niceties are that it'll tell you if you need to adjust `$PATH` or `$MANPATH` to
+access `d2` and its manpages. It can also install
+[TALA](https://github.com/terrastruct/tala) for you with `--tala`. You can also use it to
+install a specific version of `d2` with `--version`. Run it with `--help` for more more
+detailed docs on its various options and features.
+
+If you're still concerned, remember you can run with `--dry-run` to avoid writing anything.
+
+The install script does not yet verify any signature on the downloaded release
+but that is coming soon. [#315](https://github.com/terrastruct/d2/issues/315)
+
## macOS (Homebrew)
If you're on macOS, you can install with `brew`.
@@ -46,8 +77,28 @@ brew install d2
## Standalone
We publish standalone release archives for every release on Github.
-Download the `.tar.gz` release for your OS/ARCH combination and then run the following
-inside the extracted directory to install:
+
+Here's a minimal example script that downloads a standalone release, extracts it into the
+current directory and then installs it.
+Adjust VERSION, OS, and ARCH as needed.
+
+```sh
+VERSION=v0.0.13 OS=macos ARCH=amd64 curl -fsSLO \
+ "https://github.com/terrastruct/d2/releases/download/$VERSION/d2-$VERSION-$OS-$ARCH.tar.gz" \
+ && tar -xzf "d2-$VERSION-$OS-$ARCH.tar.gz" \
+ && make -sC "d2-$VERSION" install
+```
+
+To uninstall:
+
+```sh
+VERSION=v0.0.13 make -sC "d2-$VERSION" uninstall
+```
+
+### Manual
+
+You can also manually download the `.tar.gz` release for your OS/ARCH combination and then
+run the following inside the extracted directory to install:
```sh
make install
@@ -59,10 +110,11 @@ Run the following to uninstall:
make uninstall
```
-If root permissions are required for installation, you'll need to run `make` with `sudo`.
+### PREFIX
+
You can control the Unix hierarchy installation path with `PREFIX=`. For example:
-```
+```sh
# Install under ~/.local.
# Binaries will be at ~/.local/bin
# And manpages will be under ~/.local/share/man
@@ -86,6 +138,14 @@ You can always install from source:
go install oss.terrastruct.com/d2@latest
```
+To install a proper release from source clone the repository and then:
+
+```sh
+./ci/release/build.sh --install
+# To uninstall:
+# ./ci/release/build.sh --uninstall
+```
+
## Coming soon
- Docker image
diff --git a/install.sh b/install.sh
index a951260b4..f6f1c4620 100755
--- a/install.sh
+++ b/install.sh
@@ -576,6 +576,9 @@ note: Deleting the unarchived releases will cause --uninstall to stop working.
You can rerun install.sh to update your version of D2. install.sh will avoid reinstalling
if the installed version is the latest unless --force is passed.
+
+See https://github.com/terrastruct/d2/blob/master/docs/INSTALL.md#security for
+documentation on its security.
EOF
}
@@ -991,4 +994,7 @@ brew() {
HOMEBREW_NO_INSTALL_CLEANUP=1 HOMEBREW_NO_AUTO_UPDATE=1 command brew "$@"
}
+# The main function does more than provide organization. It provides robustness in that if
+# the install script was to only partial download into sh, sh will not execute it because
+# main is not invoked until the very last byte.
main "$@"