@@ -2,22 +2,95 @@
22
33Here's how to update the `npm` installer.
44
5+## 0. Overview
6+
7+- There is one _main npm package_ called `elm`.
8+- Then there is one _binary npm package_ for each platform, called for example `@evancz/elm_darwin_arm64`.
9+
10+The binary packages declare which OS and CPU they are compatible with. For example:
11+
12+```json
13+ "os": [ "darwin" ],
14+ "cpu": [ "arm64" ]
15+```
16+
17+The main npm package depend on the binary packages via [optional dependencies](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#optionaldependencies):
18+
19+```json
20+ "@evancz/elm_darwin_arm64": "0.19.1-0",
21+ "@evancz/elm_darwin_x64": "0.19.1-0",
22+ "@evancz/elm_linux_arm64": "0.19.1-0",
23+ ...
24+```
25+
26+When installing, `npm` fetches the metadata for all the optional dependencies and only installs the one with a matching OS and CPU. If none of them match, `npm` still considers the install successful. However, the main npm package contains an install script that gives a helpful error.
27+
528
629## 1. GitHub Release
730
831Create a [GitHub Release](https://github.com/elm/compiler/releases) with the following files:
932
10331. `binary-for-mac-64-bit.gz`
11−2. `binary-for-windows-64-bit.gz`
34+2. `binary-for-mac-arm-64-bit.gz`
12353. `binary-for-linux-64-bit.gz`
36+4. `binary-for-linux-arm-64-bit.gz`
37+5. `binary-for-windows-64-bit.gz`
1338
1439Create each of these by running the `elm` executable for each platform through `gzip elm`.
1540
1641
17−## 2. Try a beta release
42+## 2. Put the binaries in place
43+
44+Put the above files at:
45+
46+1. `packages/elm_darwin_arm64/elm`
47+2. `packages/elm_darwin_x64/elm`
48+3. `packages/elm_linux_x64/elm`
49+4. `packages/elm_linux_arm64/elm`
50+5. `packages/elm_win32_x64/elm.exe` (Note the `.exe` file extension!)
51+
52+(They are ignored by git.)
53+
54+
55+## 3. Publish the binary packages
56+
57+Repeat this for all the packages mentioned in the previous section. This uses `packages/elm_darwin_arm64` as an example.
58+
59+1. Go to the folder: `cd packages/elm_darwin_arm64`
60+2. Double-check that you put the right binary in the right package: `file elm`
61+3. Double-check that the file is executable: `ls -l elm`
62+4. In `package.json` of the binary package, bump the version for example to `"0.19.1-2"`.
63+5. In `package.json` of the main npm package, update `"optionalDependencies"` to point to the bumped version. For example: `"@evancz/elm_darwin_arm64": "0.19.1-2"`
64+6. Publish the package: `npm publish --access=public`
65+
66+ `--access=public` is needed because scoped packages are private by default.
67+
68+<details>
69+<summary>Notes about the versions of the binary packages</summary>
70+
71+- End users never have to think about them. They only need to think about the version of the main npm package.
72+
73+- The binary packages can have different versions. One can have `"0.19.1-0"` while another is at `"0.19.1-1"`. This is useful if you mess up publishing one platform: Then you can bump just that one and re-release, instead of having to re-release _all_ platforms.
74+
75+- The version of the main npm package is not related to the versions of the binary packages – they’re all independent. So the main npm package can be at `"0.19.1-6"` while the binary packages have suffixes like `-0`, `-1` and `-9`. (They all share the `0.19.1` prefix though to make things more understandable!)
76+
77+- The main npm package pins the versions of the binary packages _exactly_ – no version ranges.
78+ - This means that installing `elm@0.19.1-6` installs the exact same bytes in two years as today.
79+ - The `package.json` of each binary package says which OS and CPU it works for. `binary.js` in the main npm package has code that deals with OS and CPU too, so the main npm package needs to install binary packages with known OS and CPU declarations.
80+
81+- There is no need to use `beta` suffixes for the binary packages. Just bump the number suffix and point to it in a beta release of the main npm package. As mentioned above:
82+ - Already published versions of the main npm package depend on exact versions of the binary packages, so they won’t accidentally start downloading beta versions.
83+ - End users only see the version of the main npm package.
84+
85+</details>
86+
87+
88+## 4. Try a beta release
1889
1990In `package.json`, bump the version to `"0.19.2-beta"`.
2091
92+Double-check that `"optionalDependencies"` is in sync with the binary packages.
93+
2194```bash
2295npm publish --tag beta
2396```
@@ -34,7 +107,7 @@ The `latest` tag should not be changed, and there should be an additional `beta`
34107Try this on Windows, Linux, and Mac.
35108
36109
37−## 3. Publish final release
110+## 5. Publish final release
38111
39112Remove the `-beta` suffix from the version in `package.json`. Then run:
40113
@@ -43,7 +116,7 @@ npm publish
43116```
44117
45118
46−## 4. Tag the `latest-0.19.1` version
119+## 6. Tag the `latest-0.19.1` version
47120
48121Many compiler releases have needed multiple `npm` publications. Maybe something does not work on Windows or some dependency becomes insecure. Normal `npm` problems.
49122