Use one production release version source

8261bc545c9e · AtlantisPleb · · parent 74267bc7964d

Use one production release version source

Deploy story

What this commit did to the running system — joined from the forge receipt chain, the part a commit page elsewhere cannot show.

built
5 modules in 19.5 s
deployed
needs_rolling_replace · 5 modules on 0 nodes · push→live —

Changed files

  • modified Dockerfile
  • added VERSION
  • modified docs/deploymodes.md
  • modified docs/operations/forge-hot-loop.md
  • modified mix.exs
  • modified ops/deploy/build-image.sh
  • modified ops/staging/publish-candidate.sh
  • modified rel/openagents.appup.exs
  • modified test/openagents/release/appup_test.exs

Diff

9 files changed, +42 -16

Dockerfile modified +2 -1

@@ -26,7 +26,7 @@ ARG RUNNER_IMAGE="docker.io/debian:${DEBIAN_VERSION}@sha256:3a39a0592364683e6bab

26 26
FROM ${BUILDER_IMAGE} AS builder
27 27
28 28
ARG OPENAGENTS_BUILD_REVISION="image"
29
ARG OPENAGENTS_RELEASE_VSN="0.2.0"
29
ARG OPENAGENTS_RELEASE_VSN
30 30
ARG SOURCE_DATE_EPOCH=0
31 31
ARG DEBIAN_SNAPSHOT
32 32
ARG HEX_VERSION

@@ -41,6 +41,7 @@ ARG TARGETARCH

41 41
ENV OPENAGENTS_BUILD_REVISION=${OPENAGENTS_BUILD_REVISION}
42 42
ENV OPENAGENTS_RELEASE_VSN=${OPENAGENTS_RELEASE_VSN}
43 43
ENV SOURCE_DATE_EPOCH=${SOURCE_DATE_EPOCH}
44
RUN test -n "${OPENAGENTS_RELEASE_VSN}"
44 45
45 46
# install build dependencies
46 47
RUN sed -i \
VERSION added +1

@@ -0,0 +1,1 @@

1
0.2.3
docs/deploymodes.md modified +6 -6

@@ -194,12 +194,12 @@ The application version and source revision serve different purposes. A new

194 194
commit does not require a new application version when the direct path can
195 195
deploy it.
196 196
197
After a full release changes the application version, update the default in
198
`mix.exs` and the plain-release default in `rel/openagents.appup.exs` to the
199
same version. The Forge builder compiles the candidate application
200
specification from that source default, and each deployment node compares it
201
with its running release. Leaving the source default behind causes every later
202
direct candidate to fail with `runtime_toolchain_mismatch`.
197
After a full release changes the application version, update `VERSION` in the
198
same candidate. `mix.exs`, the plain appup, and both image build scripts derive
199
their default from that file. The Forge builder compiles the candidate
200
application specification with that identity, and each deployment node
201
compares it with its running release. Leaving `VERSION` behind causes every
202
later direct candidate to fail with `runtime_toolchain_mismatch`.
203 203
204 204
## Receipts and status
205 205
docs/operations/forge-hot-loop.md modified +6 -5

@@ -138,11 +138,12 @@ next patch version only when a compatible full-release package needs a new

138 138
version. Reserve a minor-version change for a deliberate compatibility or
139 139
feature boundary.
140 140
141
When a full release changes the application version, commit the same default
142
version in `mix.exs` and `rel/openagents.appup.exs`. The sidecar reads that
143
source identity into its build manifest, and deployment nodes compare it with
144
the running application. If those versions drift, direct preparation fails
145
with `runtime_toolchain_mismatch` on every node.
141
When a full release changes the application version, commit the new value in
142
`VERSION`. `mix.exs`, the plain appup, and both image build scripts derive their
143
default from that file. The sidecar reads that source identity into its build
144
manifest, and deployment nodes compare it with the running application. If
145
those versions drift, direct preparation fails with
146
`runtime_toolchain_mismatch` on every node.
146 147
147 148
If classification returns `needs_rolling_replace`, keep that receipt and use
148 149
this fallback order:
mix.exs modified +8 -1

@@ -51,7 +51,14 @@ defmodule OpenAgents.MixProject do

51 51
  end
52 52
53 53
  defp release_version do
54
    System.get_env("OPENAGENTS_RELEASE_VSN", "0.2.3")
54
    System.get_env("OPENAGENTS_RELEASE_VSN", default_release_version())
55
  end
56
57
  defp default_release_version do
58
    __DIR__
59
    |> Path.join("VERSION")
60
    |> File.read!()
61
    |> String.trim()
55 62
  end
56 63
57 64
  # Hot-upgrade-capable release: castle/forecastle add appup + relup generation
ops/deploy/build-image.sh modified +2

@@ -12,6 +12,7 @@ fi

12 12
13 13
git_sha=$(git -C "$repo_root" rev-parse --verify HEAD)
14 14
source_date_epoch=$(git -C "$repo_root" show -s --format=%ct "$git_sha")
15
release_version=$(tr -d '\n' <"$repo_root/VERSION")
15 16
platform=${OPENAGENTS_IMAGE_PLATFORM:-linux/amd64}
16 17
tag=${1:-"openagents:$git_sha"}
17 18
image_root="$git_common_dir/openagents/images"

@@ -34,6 +35,7 @@ fi

34 35
docker build \
35 36
  --platform "$platform" \
36 37
  --build-arg "OPENAGENTS_BUILD_REVISION=$git_sha" \
38
  --build-arg "OPENAGENTS_RELEASE_VSN=$release_version" \
37 39
  --build-arg "SOURCE_DATE_EPOCH=$source_date_epoch" \
38 40
  --iidfile "$iid_file" \
39 41
  --label "org.opencontainers.image.revision=$git_sha" \
ops/staging/publish-candidate.sh modified +9 -2

@@ -47,6 +47,7 @@ fi

47 47
git_sha=$(git rev-parse --verify HEAD)
48 48
origin_main=$(git rev-parse --verify refs/remotes/origin/main)
49 49
source_date_epoch=$(git show -s --format=%ct "$git_sha")
50
release_version=$(tr -d '\n' <"$repo_root/VERSION")
50 51
51 52
if [ "$git_sha" != "$origin_main" ]; then
52 53
  echo "candidate must equal the locally fetched origin/main commit" >&2

@@ -184,6 +185,7 @@ else

184 185
  docker build \
185 186
    --platform "$platform" \
186 187
    --build-arg "OPENAGENTS_BUILD_REVISION=$git_sha" \
188
    --build-arg "OPENAGENTS_RELEASE_VSN=$release_version" \
187 189
    --build-arg "SOURCE_DATE_EPOCH=$source_date_epoch" \
188 190
    --iidfile "$builder_iid" \
189 191
    --label "org.opencontainers.image.revision=$git_sha" \

@@ -274,8 +276,13 @@ case "$archive_name" in

274 276
  *) echo "builder image does not contain one release archive" >&2; exit 1 ;;
275 277
esac
276 278
277
release_version=${archive_name#openagents-}
278
release_version=${release_version%.tar.gz}
279
archive_version=${archive_name#openagents-}
280
archive_version=${archive_version%.tar.gz}
281
282
if [ "$archive_version" != "$release_version" ]; then
283
  echo "builder archive version does not match VERSION" >&2
284
  exit 1
285
fi
279 286
builder_container=$(docker create "$builder_image")
280 287
docker cp "$builder_container:/app/_build/prod/$archive_name" "$candidate_temp/$archive_name" >/dev/null
281 288
docker rm "$builder_container" >/dev/null
rel/openagents.appup.exs modified +1 -1

@@ -40,7 +40,7 @@

40 40
       )
41 41
42 42
     is_nil(to) and is_nil(from) ->
43
       {String.to_charlist(System.get_env("OPENAGENTS_RELEASE_VSN", "0.2.3")), [], []}
43
       {String.to_charlist(Mix.Project.config()[:version]), [], []}
44 44
45 45
     true ->
46 46
       raise "RELUP_FROM and RELUP_TO must be set together"
test/openagents/release/appup_test.exs modified +7

@@ -13,6 +13,8 @@ defmodule OpenAgents.Release.AppupTest do

13 13
  alias OpenAgents.Release.Appup
14 14
15 15
  @appup_file Path.expand("../../../rel/openagents.appup.exs", __DIR__)
16
  @dockerfile Path.expand("../../../Dockerfile", __DIR__)
17
  @version_file Path.expand("../../../VERSION", __DIR__)
16 18
  @environment [
17 19
    "OPENAGENTS_RELEASE_VSN",
18 20
    "RELUP_FROM",

@@ -39,8 +41,13 @@ defmodule OpenAgents.Release.AppupTest do

39 41
  test "plain releases keep the appup and project versions aligned" do
40 42
    Enum.each(@environment, &System.delete_env/1)
41 43
44
    assert String.trim(File.read!(@version_file)) == Mix.Project.config()[:version]
45
42 46
    assert {String.to_charlist(Mix.Project.config()[:version]), [], []} ==
43 47
             @appup_file |> Code.eval_file() |> elem(0)
48
49
    assert File.read!(@dockerfile) =~ "ARG OPENAGENTS_RELEASE_VSN\n"
50
    refute File.read!(@dockerfile) =~ "ARG OPENAGENTS_RELEASE_VSN="
44 51
  end
45 52
46 53
  test "covers a changed module the fixed proof set never named" do

This page updates live while a promote is in flight · changelog