Skip to content

Commit 7a6d033

Browse files
authored
Merge pull request #36 from ausimian/issue/9-readme-task-provenance
docs: document the build-time tasks as castle.*
2 parents 04d05f9 + 5742bcc commit 7a6d033

6 files changed

Lines changed: 60 additions & 17 deletions

File tree

AGENTS.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ which is precisely what `customize/1` exists to prevent. Mix validates `:steps`
11971197
**It changes exactly one option.** What a consumer still has to declare by hand
11981198
is listed in the `@doc`, because the alternative is finding out from a failed
11991199
upgrade: the `:appup` project key with `compilers: Mix.compilers() ++ [:appup]`,
1200-
a relup from `mix forecastle.relup` left in the project root, and
1200+
a relup from `mix castle.relup` left in the project root, and
12011201
`include_executables_for: [:unix]` — Windows is unsupported and assembly only
12021202
warns — plus the optional `rel/env.sh.eex`. `:steps` is the one option whose
12031203
contents are Castle's business; the others are the project's own choices, and
@@ -1920,10 +1920,22 @@ the exit statuses `bin/castle` returns are asserted. None of it is measured here
19201920
refuses: `mix docs` catches a broken *reference*, and nothing at all catches a
19211921
true sentence that has stopped being true. Both are read against
19221922
`Castle.Commands` by hand.
1923-
- **The README is out of date.** It documents an `:appup` compiler and a
1924-
`mix castle.relup` task that moved to Forecastle in 0.3.0, the release
1925-
management commands it describes on `bin/<release>` now live on `bin/castle`,
1926-
and its integration section still tells a consumer to place
1927-
`Forecastle.pre_assemble/1` and `Forecastle.post_assemble/1` around
1928-
`:assemble` by hand, which is what `Castle.customize/1` replaced
1929-
([#9](https://github.com/ausimian/castle/issues/9)).
1923+
- **Nothing runs the README's build-time instructions the way a consumer would,
1924+
and the gap is narrower than "there is no test".** Forecastle's suite
1925+
exercises `mix castle.relup` and the `:appup` compiler thoroughly — but its
1926+
sample fixture takes Forecastle as a `path` dependency with `override: true`,
1927+
so what it establishes is that the implementations work, not the claim this
1928+
README actually makes: that depending on **Castle alone** is enough to get
1929+
them. Neither repository runs that flow, and the `override:` is deliberate
1930+
(Forecastle has to be testable without Castle's API), so it is not something
1931+
to fix by tidying the fixture.
1932+
1933+
That is not hypothetical. Closing
1934+
[#9](https://github.com/ausimian/castle/issues/9) documented
1935+
`mix castle.relup` here while `mix.lock` still pinned a Forecastle from before
1936+
[forecastle#24](https://github.com/ausimian/forecastle/issues/24) renamed it —
1937+
so a clean checkout honouring the committed lock had no such task, and the
1938+
whole suite stayed green. Advancing the pin is what made the documentation
1939+
true. Until a consumer-shaped fixture exists, the check is manual: read the
1940+
lock against Forecastle's task surface whenever either side of the pair
1941+
changes.

README.md

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,10 @@ the launcher setup Castle needs.
8080

8181
## Appups and relups
8282

83-
Write an appup for each application whose code changes during a hot upgrade.
84-
The appup file uses Erlang terms written in Elixir syntax:
83+
Write an appup for each application you own that has to be upgraded in place.
84+
Whether a given transition needs one depends on the strategy below and on which
85+
applications changed; `mix castle.relup` documents the rules. The appup file
86+
uses Erlang terms written in Elixir syntax:
8587

8688
```elixir
8789
{
@@ -98,7 +100,7 @@ The appup file uses Erlang terms written in Elixir syntax:
98100
Generate a relup between assembled releases:
99101

100102
```shell
101-
mix forecastle.relup \
103+
mix castle.relup \
102104
--target _build/prod/rel/my_app/releases/1.1.0/my_app \
103105
--fromto _build/prod/rel/my_app/releases/1.0.0/my_app
104106
```
@@ -107,6 +109,14 @@ The task writes `relup` to the project root by default. Leave it there for the
107109
next release build to package. Use `--hot` to require a hot transition or
108110
`--restart` to force a one-stage emulator restart.
109111

112+
`mix castle.relup` is implemented in Forecastle, which Castle brings in as a
113+
build-time dependency. It is named for Castle because that is the package a
114+
project depends on, and nothing has to be added to `deps` to get it.
115+
116+
The appup compiler comes from Forecastle the same way, but is named for what it
117+
does rather than for either package: it stays `mix compile.appup`, reached
118+
through the `:compilers` list above. There is no `mix castle.appup`.
119+
110120
## Managing releases
111121

112122
Build the new release, then copy `<name>-<vsn>.tar.gz` into the running

RELEASE.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,15 @@ Forecastle 1.x and Elixir 1.18 or later.
2121

2222
### Changed
2323

24+
- `mix forecastle.relup` is now `mix castle.relup`, and the README documents it
25+
as Castle's while naming Forecastle as its implementer. There is no
26+
compatibility alias, so a build pipeline calling the old name has to be
27+
updated. Nothing changes in `deps` — Castle already brings Forecastle in at
28+
build time, and which half implements a task is a packaging decision rather
29+
than something a consumer should have to learn. The appup compiler is **not**
30+
renamed and is unaffected: it stays `mix compile.appup`, named by its
31+
`:compilers` entry rather than by either package.
32+
([forecastle#24](https://github.com/ausimian/forecastle/issues/24))
2433
- Release-management commands now raise on refusal or a returned OTP error, so
2534
`bin/castle` exits non-zero. Successful command output is unchanged.
2635
- Operator-facing errors and warnings are shorter, distinguish preflight

design/upgrade-tooling.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Upgrade tooling: appups, relups, and the tasks around them
22

3-
**Status:** accepted, unimplemented. Supersedes nothing.
3+
**Status:** accepted. D1 is implemented — the tasks are named `castle.*` as of
4+
[forecastle#24](https://github.com/ausimian/forecastle/issues/24), enforced by
5+
[castle#33](https://github.com/ausimian/castle/issues/33). The rest is
6+
unimplemented. Supersedes nothing.
47
**Spans:** [ausimian/castle](https://github.com/ausimian/castle) and
58
[ausimian/forecastle](https://github.com/ausimian/forecastle).
69
**Tracked by:** [castle#32](https://github.com/ausimian/castle/issues/32).
@@ -55,7 +58,7 @@ appup lookups in `appup_file/2` — and those only exist **after** `:assemble`.
5558
So the real workflow is:
5659

5760
1. `mix release` — assemble the target.
58-
2. `mix forecastle.relup --target … --fromto …` — write `relup` to the project root.
61+
2. `mix castle.relup --target … --fromto …` — write `relup` to the project root.
5962
3. `mix release --overwrite` — assemble it again, this time packaging the relup.
6063

6164
The double build is mandatory and undocumented. Worse, it makes a mutable file in

lib/castle.ex

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,18 @@ defmodule Castle do
6565
6666
The project must also provide:
6767
68-
* An appup for each application being upgraded, configured with the
69-
`:appup` project key and `compilers: Mix.compilers() ++ [:appup]`.
70-
* A relup generated by `mix forecastle.relup` and left in the project root.
68+
* An appup for each application the project owns that has to be upgraded in
69+
place, configured with the `:appup` project key and
70+
`compilers: Mix.compilers() ++ [:appup]`.
71+
72+
Exactly which transitions need one depends on the strategy the relup is
73+
generated with, on which applications changed and on who owns them, and
74+
each direction is classified separately. `mix castle.relup` documents
75+
those rules and is the authority on them; this list deliberately does not
76+
restate them, because a summary short enough to belong here is wrong in
77+
some case and a correct one is that task's `@moduledoc` copied into a
78+
repository that cannot see it change.
79+
* A relup generated by `mix castle.relup` and left in the project root.
7180
* `include_executables_for: [:unix]`.
7281
7382
A custom `rel/env.sh.eex` is optional. Forecastle appends Castle's setup to

mix.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"earmark_parser": {:hex, :earmark_parser, "1.4.46", "67607a0532e810c6f630a515c548d0b24949643f168cc556303bee4cf96105c7", [:mix], [], "hexpm", "9c44636e8a1c68c62f526b2dcd85d941dbbcee7ab82cf64ba06ce28bef8e89f5"},
55
"ex_doc": {:hex, :ex_doc, "0.40.3", "4a972ffe64bc07dc605af487e98fc19b72a4185f55ca031b94c0552d6071c1d9", [:mix], [{:earmark_parser, "~> 1.4.44", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.0", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14 or ~> 1.0", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1 or ~> 1.0", [hex: :makeup_erlang, repo: "hexpm", optional: false]}, {:makeup_html, ">= 0.1.0", [hex: :makeup_html, repo: "hexpm", optional: true]}], "hexpm", "2756e357742fecd9749b489b85d67c9ce99c465f2e75728d9e6dc8d704b973de"},
66
"file_system": {:hex, :file_system, "1.1.1", "31864f4685b0148f25bd3fbef2b1228457c0c89024ad67f7a81a3ffbc0bbad3a", [:mix], [], "hexpm", "7a15ff97dfe526aeefb090a7a9d3d03aa907e100e262a0f8f7746b78f8f87a5d"},
7-
"forecastle": {:git, "https://github.com/ausimian/forecastle.git", "e43f8808a4470a6952013cc8af56bec64877ef89", [branch: "feature/upgrade-tooling"]},
7+
"forecastle": {:git, "https://github.com/ausimian/forecastle.git", "a77e97c9f14b07ca4e532ff98e626a6106548cba", [branch: "feature/upgrade-tooling"]},
88
"jason": {:hex, :jason, "1.4.5", "2e3a008590b0b8d7388c20293e9dcc9cf3e5d642fd2a114e4cbbb52e595d940a", [:mix], [{:decimal, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b0c823996102bcd0239b3c2444eb00409b72f6a140c1950bc8b457d836b30684"},
99
"makeup": {:hex, :makeup, "1.2.2", "882d46dc0905e9ff7abf2aab61a7e6b3dcc555533977d8a23b06019e6c89ac94", [:mix], [{:nimble_parsec, "~> 1.4", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "9a1a24e5b343b8ae16abea0822c10a6f75da27af7fa802ada5251f7579bfccfa"},
1010
"makeup_elixir": {:hex, :makeup_elixir, "1.0.1", "e928a4f984e795e41e3abd27bfc09f51db16ab8ba1aebdba2b3a575437efafc2", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "7284900d412a3e5cfd97fdaed4f5ed389b8f2b4cb49efc0eb3bd10e2febf9507"},

0 commit comments

Comments
 (0)