Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
114 commits
Select commit Hold shift + click to select a range
d324584
test: prove the built DAR is consumable on its own
lmcorbalan Aug 28, 2026
9c490e9
fix: list the consumer smoke package in the template-id check
lmcorbalan Aug 28, 2026
0d09af6
fix: build the DAR and read its version in the consumer smoke test
lmcorbalan Aug 28, 2026
12ad469
chore: clean the consumer smoke output and document npm run smoke
lmcorbalan Aug 28, 2026
70e1349
fix: pick the consumer smoke DAR by the version in daml.yaml
lmcorbalan Aug 28, 2026
611d21b
fix: set LANG unconditionally in the consumer smoke script
lmcorbalan Aug 28, 2026
2f889a5
fix: assert the SDK pin in every tracked daml.yaml
lmcorbalan Aug 28, 2026
f7542c1
docs: correct the daml.yaml pin counts and record the consumer smoke …
lmcorbalan Aug 28, 2026
68bd9b4
fix: pick the sandbox DAR by the version in daml.yaml
lmcorbalan Aug 28, 2026
61350e9
ci: run the SDK pin assertion ahead of the scope gate
lmcorbalan Aug 28, 2026
c4bc997
docs: correct the daml.yaml counts in README and versions.env
lmcorbalan Aug 28, 2026
6505363
Merge pull request #149 from BootNodeDev/chore/release/task-1-consume…
lmcorbalan Aug 28, 2026
098ff31
build: generate the release body from the smoke test package
lmcorbalan Aug 28, 2026
9fe82b2
fix: fail loudly when the SDK pin or SPLICE_TAG cannot be read
lmcorbalan Aug 31, 2026
acd95d0
fix: report the failure instead of dying silently at the assignment
lmcorbalan Aug 31, 2026
b1fda5d
fix: read the consumer snippet block by block instead of to end of file
lmcorbalan Aug 31, 2026
99941ae
fix: hash the DAR with shasum where GNU sha256sum is absent
lmcorbalan Aug 31, 2026
bc0def5
fix: publish the bare package-id rather than the prefixed dalf name
lmcorbalan Aug 31, 2026
6296082
fix: refuse a block whose entries are gone, not just a missing block
lmcorbalan Aug 31, 2026
803f757
fix: build the DAR before describing it, as the smoke script does
lmcorbalan Aug 31, 2026
88d569f
docs: describe what the script proves and what it leaves to npm run s…
lmcorbalan Aug 31, 2026
c837d7b
fix: name the missing unzip instead of blaming the DAR
lmcorbalan Aug 31, 2026
454843f
docs: warn that both published blocks are downstream-facing, not just…
lmcorbalan Aug 31, 2026
a4e8d29
fix: refuse to publish package flags the DAR does not bundle
lmcorbalan Aug 31, 2026
74a48f9
fix: refuse to describe a build that no commit at that tag produces
lmcorbalan Aug 31, 2026
2e60b87
fix: refuse to publish when git cannot report the tree state
lmcorbalan Aug 31, 2026
27b1c09
fix: require a real tag, not any commit-ish that resolves
lmcorbalan Aug 31, 2026
0d9552c
fix: refuse a snippet that omits a bundled interface package
lmcorbalan Aug 31, 2026
72fc42a
docs: derive the published count, LF target and vendor path from the …
lmcorbalan Aug 31, 2026
8be25b4
fix: check the not-included package is really absent from the DAR
lmcorbalan Aug 31, 2026
055780e
Merge pull request #150 from BootNodeDev/chore/release/task-2-release…
lmcorbalan Aug 31, 2026
5e0fe47
ci: publish the built DAR as a release asset on tag push
lmcorbalan Aug 31, 2026
a77df8d
fix: surface the LF-target diagnostic instead of dying at the grep
lmcorbalan Aug 31, 2026
83834b7
ci: stop persisting the checkout credential in the release job
lmcorbalan Aug 31, 2026
a9c0fc2
fix: publish a pre-release tag as a pre-release
lmcorbalan Aug 31, 2026
905a0e5
docs: correct the manifest count in the release workflow install comment
lmcorbalan Aug 31, 2026
3215272
docs: correct what a dispatched run's ref name can be
lmcorbalan Aug 31, 2026
856f052
fix: publish the DAR the job verified rather than a later rebuild
lmcorbalan Aug 31, 2026
7a4e4ae
docs: say plainly that this file spells out the LF target
lmcorbalan Aug 31, 2026
b7ab84e
docs: name the one check a dispatched run does not make
lmcorbalan Aug 31, 2026
7076484
Merge pull request #151 from BootNodeDev/chore/release/task-3-release…
lmcorbalan Aug 31, 2026
e212f46
docs: document consuming and cutting a release
lmcorbalan Aug 31, 2026
1341c8b
docs: say a release run does exercise the smoke test
lmcorbalan Aug 31, 2026
80f5e04
docs: stop claiming both release scripts read both knobs
lmcorbalan Aug 31, 2026
045e0f6
docs: warn that the preview command refuses a dirty tree
lmcorbalan Aug 31, 2026
2c76c09
docs: name the pre-release tag that rehearses the publish step
lmcorbalan Aug 31, 2026
813ea3d
docs: point the dirty-tree remedy at untracked files
lmcorbalan Aug 31, 2026
3d53771
docs: count the smoke test among the checks no pull request runs
lmcorbalan Aug 31, 2026
ae0dd2b
docs: name both versioning exceptions when bumping splice
lmcorbalan Aug 31, 2026
79411d6
docs: match the step count in the pull-request check summary
lmcorbalan Aug 31, 2026
9a62b52
docs: say what the release-notes command refuses
lmcorbalan Aug 31, 2026
06504db
docs: link the release procedure from the workflow description
lmcorbalan Aug 31, 2026
f9d7218
Merge pull request #153 from BootNodeDev/chore/release/task-4-release…
lmcorbalan Aug 31, 2026
3d69e98
ci: run the consumer smoke test on pull requests
lmcorbalan Aug 31, 2026
45d1df7
docs: say that a pull request runs the consumer smoke test
lmcorbalan Aug 31, 2026
d337662
ci: describe the scope gate by the paths it lists
lmcorbalan Aug 31, 2026
22adc4e
ci: say why the smoke step skips the build
lmcorbalan Aug 31, 2026
80716f4
docs: name every path that scopes a pull request into the daml check
lmcorbalan Aug 31, 2026
a9a7d4c
docs: stop calling two commands the only checks off the pull-request …
lmcorbalan Aug 31, 2026
af454ac
docs: drop the vacuous scope clause from the smoke sentence
lmcorbalan Aug 31, 2026
ee7ef59
docs: say which half of downstream consumability a pull request checks
lmcorbalan Aug 31, 2026
906a194
docs: stop counting the checks that skip the pull-request path
lmcorbalan Aug 31, 2026
d1cf70e
ci: stop claiming a tracked manifest sits outside the scope gate
lmcorbalan Aug 31, 2026
0237163
docs: name every event on which ci.yml runs the smoke test
lmcorbalan Aug 31, 2026
87d3759
docs: stop putting every release-workflow check off the pull-request …
lmcorbalan Aug 31, 2026
6ef34c9
docs: name the build input whose bump the smoke test exists to catch
lmcorbalan Aug 31, 2026
b335918
docs: count the reproducibility rebuild among the release-only checks
lmcorbalan Aug 31, 2026
44b6973
docs: rewrap the paragraph the smoke-test edits left ragged
lmcorbalan Aug 31, 2026
acadba1
Merge pull request #154 from BootNodeDev/ci/pr-consumer-smoke
lmcorbalan Aug 31, 2026
4cc46d1
test: exercise every interface instance in the consumer smoke package
lmcorbalan Aug 31, 2026
95922a7
fix: count the interface packages the DAR bundles, not the snippet's …
lmcorbalan Aug 31, 2026
251398e
ci: run the release-notes generator on the pull-request path
lmcorbalan Aug 31, 2026
87b0b8d
ci: re-vendor between the two reproducibility builds
lmcorbalan Aug 31, 2026
afa46ec
ci: record the vendored Splice commit in the release body
lmcorbalan Aug 31, 2026
ac5c039
ci: attach the asset separately so a failed upload can be retried
lmcorbalan Aug 31, 2026
465d0f8
ci: refuse to publish a tag that main does not reach
lmcorbalan Aug 31, 2026
44e5e76
docs: rehearse a release by compiling against the downloaded asset
lmcorbalan Aug 31, 2026
5396f69
ci: install dpm from one shared action instead of a copy per workflow
lmcorbalan Aug 31, 2026
3a670c8
docs: name the workflow pins among the Splice bump edits
lmcorbalan Aug 31, 2026
3ac9149
docs: correct the over-general sentences this fix wave introduced
lmcorbalan Aug 31, 2026
196033e
fix: reach the commit-resolution guard when ls-remote itself fails
lmcorbalan Aug 31, 2026
a9503d3
fix: refuse an unresolved commit before replacing the vendored tree
lmcorbalan Aug 31, 2026
5b71d41
fix: refuse a release body whose vendored tree predates the pinned tag
lmcorbalan Aug 31, 2026
1599d83
ci: anchor the LF-target assertion to the whole manifest entry
lmcorbalan Aug 31, 2026
b6bbe62
ci: assert the LF target on the pull-request path, not only at tag push
lmcorbalan Aug 31, 2026
17e8230
ci: refuse an off-main tag before the build rather than after it
lmcorbalan Aug 31, 2026
77cd761
ci: say why the install refuses a non-x86_64 runner
lmcorbalan Aug 31, 2026
01e7939
docs: stop claiming the type tuple is the only reach to four packages
lmcorbalan Aug 31, 2026
15828ac
docs: say the README snippet is transcribed rather than derived
lmcorbalan Aug 31, 2026
0095386
docs: point the failed-upload recovery at re-running the tag push
lmcorbalan Aug 31, 2026
080d179
docs: clear the consumer build tree before compiling the downloaded a…
lmcorbalan Aug 31, 2026
cb37ce7
docs: count the three checks a dispatched release run cannot reach
lmcorbalan Aug 31, 2026
0975939
docs: correct which release checks a pull request now runs
lmcorbalan Aug 31, 2026
f322292
docs: correct the over-general sentences this fix wave introduced
lmcorbalan Aug 31, 2026
0ef3022
ci: refuse a manifest carrying a second --target entry beside the pin…
lmcorbalan Aug 31, 2026
c58c7a7
fix: reach the version-derivation guard when the manifest names no ve…
lmcorbalan Aug 31, 2026
b813a30
fix: vendor the tarball fallback even when the commit cannot be resolved
lmcorbalan Aug 31, 2026
3e6e57e
ci: trigger the release only on a tag whose v is followed by a digit
lmcorbalan Aug 31, 2026
2cfe157
fix: write the vendoring stamp once the stable-name symlinks exist
lmcorbalan Aug 31, 2026
1885bde
ci: refresh the release body when the release already exists
lmcorbalan Aug 31, 2026
182c00a
ci: compare the README consumer snippet against the smoke package
lmcorbalan Aug 31, 2026
27d60cd
ci: describe the ungated steps as a property rather than a count
lmcorbalan Aug 31, 2026
4fc75d1
docs: name the LF target and the README snippet among the ungated checks
lmcorbalan Aug 31, 2026
13b199e
docs: describe Consumer.daml by the conversions rather than the type …
lmcorbalan Aug 31, 2026
9a0a345
docs: correct the over-general and false claims this fix wave introduced
lmcorbalan Aug 31, 2026
531c2d3
ci: pass the snippet comparison patterns to grep after a terminator
lmcorbalan Aug 31, 2026
2385f72
fix: refuse a DAR carrying more than one package-id for the main package
lmcorbalan Aug 31, 2026
2c9c948
ci: re-apply the release marking when refreshing an existing release
lmcorbalan Aug 31, 2026
50ce852
ci: compare the two block headers of the README consumer snippet
lmcorbalan Aug 31, 2026
0ae5b9a
docs: say what the README snippet check compares rather than that it …
lmcorbalan Aug 31, 2026
1210128
docs: name the release trigger as the glob the workflow actually carries
lmcorbalan Aug 31, 2026
2dcb10c
ci: describe the gated scripts as a property rather than a count
lmcorbalan Aug 31, 2026
23edc8a
docs: name the guard ALLOW_UNTAGGED actually waives
lmcorbalan Aug 31, 2026
de0e5dd
docs: correct the count, the unmeasured outcomes and the false strip …
lmcorbalan Aug 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions .github/actions/install-dpm/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
name: install dpm
description: >
Install the pinned dpm SDK, having first asserted that every tracked daml.yaml
pins the same version. Shared by ci.yml and release.yml so the download, the
digest that verifies it and the sweep exist once rather than once per workflow.

inputs:
sdk-version:
description: >
The dpm SDK version to install. Passed in rather than defaulted here
because ci.yml needs the same value in a step that runs before this one,
outside its scope gate and without a toolchain.
required: true

runs:
using: composite
steps:
- shell: bash
env:
DPM_SDK_VERSION: ${{ inputs.sdk-version }}
run: |
set -euo pipefail
# Only the linux-amd64 tarball is fetched below and only its digest is
# recorded, so another architecture has nothing to install. Reported
# rather than left to a bare `test`, which exits 1 printing nothing and
# reads as the download having failed; this action is shared with the
# release workflow, where that silence would be the whole explanation
# of a failed release.
arch="$(uname -m)"
if [ "$arch" != x86_64 ]; then
echo "install-dpm supports x86_64 only, this runner is ${arch}" >&2
exit 1
fi
# The digest lives here and only here. A caller supplies the version it
# wants and this refuses any version it has no recorded hash for, so a
# bump cannot quietly install an unverified tarball: it has to be
# accompanied by the hash of the new one.
case "$DPM_SDK_VERSION" in
3.4.11) tarball_sha256='177328b8d8b5781a6eee37fbd172a8445f18e07b46292c40fe32207d4cd72ccd' ;;
*)
echo "no recorded tarball digest for dpm ${DPM_SDK_VERSION}" >&2
echo " add it to .github/actions/install-dpm/action.yml" >&2
exit 1
;;
esac
# Discovered rather than listed, because a package added later carries a
# pin of its own and a list written today cannot name it.
pins="$(git ls-files '*daml.yaml')"
if [ -z "$pins" ]; then
echo "no daml.yaml is tracked, so the SDK pin went unchecked" >&2
exit 1
fi
while read -r manifest; do
pinned="$(awk '/^sdk-version:/ {print $2; exit}' "$manifest")"
if [ "$pinned" != "$DPM_SDK_VERSION" ]; then
echo "${manifest} pins SDK ${pinned}, this workflow installs ${DPM_SDK_VERSION}" >&2
exit 1
fi
echo "ok: ${manifest} pins SDK ${pinned}"
done <<<"$pins"
# The published tarball is fetched by exact version and checked against
# the recorded digest instead of piping an installer into a shell.
# Pinning is also a correctness requirement, not only a supply-chain
# one: the installer's "latest" resolves to 3.5.5, while every tracked
# daml.yaml pins 3.4.11.
tarball="dpm-${DPM_SDK_VERSION}-linux-amd64.tar.gz"
url="https://artifactregistry.googleapis.com/download/v1/projects/da-images/locations/europe/repositories/public-generic/files/dpm-sdk:${DPM_SDK_VERSION}:${tarball}:download?alt=media"
curl -SLf --retry 3 --retry-all-errors --retry-delay 5 \
"$url" --output "${RUNNER_TEMP}/${tarball}"
echo "${tarball_sha256} ${RUNNER_TEMP}/${tarball}" | sha256sum -c -
mkdir -p "${RUNNER_TEMP}/dpm-extracted"
tar xzf "${RUNNER_TEMP}/${tarball}" -C "${RUNNER_TEMP}/dpm-extracted" --strip-components 1
"${RUNNER_TEMP}/dpm-extracted/bin/dpm" bootstrap "${RUNNER_TEMP}/dpm-extracted"
rm -rf "${RUNNER_TEMP}/${tarball}" "${RUNNER_TEMP}/dpm-extracted"
echo "$HOME/.dpm/bin" >> "$GITHUB_PATH"
228 changes: 189 additions & 39 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ jobs:
# dies with a UTF-8 decoding error under a C or POSIX locale.
LANG: C.UTF-8
DPM_SDK_VERSION: '3.4.11'
DPM_TARBALL_SHA256: '177328b8d8b5781a6eee37fbd172a8445f18e07b46292c40fe32207d4cd72ccd'
steps:
- uses: actions/checkout@v4
with:
Expand Down Expand Up @@ -175,6 +174,9 @@ jobs:
fi
checked=(
RUNBOOK.md
# Listed to keep the comparison below exhaustive. Unlike the rest,
# this file's imports are compiler-checked, by `npm run smoke`.
consumer-smoke/consumer/daml/Consumer.daml
registry/.env.example
registry/test/e2e/helpers/sandbox.ts
registry/test/helpers/fixtures.ts
Expand Down Expand Up @@ -291,6 +293,135 @@ jobs:
done
exit "$status"

# README.md's "Consuming a release" snippet is a hand transcription of
# the two blocks scripts/release-notes.sh cuts from the smoke package,
# and it is the first page a consumer reads. Nothing else compared the
# two: a SPLICE_TAG bump that ships new interface versions reds this
# job through the smoke package, the author fixes that daml.yaml, CI
# goes green, and README still tells a consumer to write the flags we
# moved off. Ungated for the same reason the step above is, and because
# README.md appears in the gate's path list nowhere at all, so a change
# to either file has to be able to red this.
- name: Verify the README consumer snippet
run: |
set -euo pipefail
smoke=consumer-smoke/consumer/daml.yaml
# The vendor path, the LF target and the --package flags: the lines
# a consumer copies. Selected by their leading '- --' or
# '- vendor/' rather than by parsing the YAML blocks, which is what
# keeps the dependencies: entries (daml-prim, daml-stdlib) out
# without a second block parser living here.
pattern='^[[:space:]]*-[[:space:]]*(--|vendor/)'
# The entries alone do not make a snippet. Nothing else here ties
# one to the block it belongs under, so README could carry every
# entry line with build-options: renamed, dropped, or the --package
# flags moved under data-dependencies:, and each comparison below
# would still match. Measured on the smoke package with the header
# renamed: dpm accepts the file, ignores the key it does not know,
# and the imports fail on "member of the hidden package", the same
# error a consumer gets with the flags missing altogether, which is
# what this whole section exists to prevent. The generated release
# body cannot drift this way: yaml_block cuts each header out of the
# smoke package itself.
for header in data-dependencies: build-options:; do
if ! grep -qxF -- "$header" README.md; then
echo "README.md does not carry the '${header}' block header" >&2
exit 1
fi
done
# A grep that matches nothing exits 1, which under -e kills the
# step at the assignment and leaves the emptiness report below
# unreachable.
from_smoke="$(grep -E "$pattern" "$smoke" || true)"
if [ -z "$from_smoke" ]; then
echo "${smoke} names no --package, --target or vendor entry" >&2
exit 1
fi
from_readme="$(grep -E "$pattern" README.md || true)"
status=0
# Both directions. The first catches a flag README never followed
# the smoke package onto; the second catches one it kept after the
# smoke package dropped it, which is the quieter of the two because
# every line still present is individually valid.
#
# The two comparisons below, and the header loop above, take their
# pattern after '--'. The selection pattern allows no leading
# whitespace, and unindented block entries build green under dpm, so
# a manifest reformatted that way hands grep a pattern beginning
# with '-'. Without the terminator grep reads that as an option
# cluster and exits 2, which '!' turns into "README.md does not
# carry" a line it carries verbatim.
while IFS= read -r line; do
if ! grep -qxF -- "$line" README.md; then
echo "README.md does not carry '${line}' from ${smoke}" >&2
status=1
fi
done <<<"$from_smoke"
while IFS= read -r line; do
[ -n "$line" ] || continue
if ! grep -qxF -- "$line" "$smoke"; then
echo "README.md carries '${line}', which ${smoke} does not" >&2
status=1
fi
done <<<"$from_readme"
if [ "$status" = 0 ]; then
echo "ok: README.md's snippet matches ${smoke}"
fi
exit "$status"

# DPM_SDK_VERSION is one more copy of a pin whose other homes are the
# daml.yaml files. Assert rather than trust: bumping those and forgetting
# this one otherwise fails much later, or silently makes dpm download a
# second SDK. Discovered rather than listed, because a package added
# later carries a pin of its own and a list written today cannot name it.
# Ungated for the same reason the step above is: the sweep discovers its
# manifests instead of reading the gate's list, so gating it would let a
# pull request that bumps a manifest the gate does not list pass while
# the merge to main reds. Every tracked manifest sits inside the gate
# today, but that list is written by hand and this sweep is not. It needs
# no toolchain, only the checkout, so it can run here rather than beside
# the install it guards.
# The LF target is swept here as well as in release.yml. It used to be
# asserted only there, which meant a manifest moved off 2.1 built, tested
# and merged green, and first reded on the tag push, with the tag already
# public. The two sweeps read the same manifests for the same literal;
# keeping release.yml's is what makes the one run whose output is
# permanent self-contained rather than trusting a check in another file.
- name: Verify the SDK and LF pins
run: |
set -euo pipefail
pins="$(git ls-files '*daml.yaml')"
if [ -z "$pins" ]; then
echo "no daml.yaml is tracked, so the SDK pin went unchecked" >&2
exit 1
fi
while read -r manifest; do
pinned="$(awk '/^sdk-version:/ {print $2; exit}' "$manifest")"
if [ "$pinned" != "$DPM_SDK_VERSION" ]; then
echo "${manifest} pins SDK ${pinned}, this workflow installs ${DPM_SDK_VERSION}" >&2
exit 1
fi
# Anchored to the whole entry: a substring match counts a
# commented-out line, and matches --target=2.10 as readily as 2.1.
# A grep that matches nothing exits 1, which under -e would kill
# the step here and leave the report below unreachable.
#
# Counted twice, because the anchored count says only that a live
# 2.1 entry is present, never that it is the only one. A second
# entry beside it leaves the manifest naming a target nothing
# here has inspected, whichever of the two damlc ends up using,
# and it reaches release-notes.sh as an LF row carrying two
# values. Counting every entry as well is what closes both.
entries="$(grep -cE '^[[:space:]]*-[[:space:]]*--target=' "$manifest" || true)"
target="$(grep -cE '^[[:space:]]*-[[:space:]]*--target=2\.1[[:space:]]*$' "$manifest" || true)"
if [ "$entries" != 1 ] || [ "$target" != 1 ]; then
echo "${manifest} must carry exactly one --target entry, naming LF 2.1;" \
"found ${entries} entries, ${target} of them 2.1" >&2
exit 1
fi
echo "ok: ${manifest} pins SDK ${pinned} and targets LF 2.1"
done <<<"$pins"

- name: Scope
id: scope
env:
Expand All @@ -304,9 +435,9 @@ jobs:
exit 0
fi
# A blip on this fetch reds the job having verified nothing, so it
# is retried rather than taken at its word. The template-id step is
# ungated so that it runs whatever the change touches; it sits above
# this one so that a red here finds it already run and reported,
# is retried rather than taken at its word. Every step above this
# one is ungated, so they run whatever the change touches; they sit
# above it so that a red here finds them already run and reported,
# rather than never run at all.
for attempt in 1 2 3; do
git fetch --no-tags --prune origin \
Expand All @@ -318,12 +449,15 @@ jobs:
changed="$(git -c core.quotePath=false diff --name-only --no-renames "origin/${BASE_REF}...HEAD")"
echo "Changed files:"
echo "$changed"
# Build and test inputs only. The files that merely name template
# ids are not listed: the check that reads them runs ahead of this
# gate and ignores it, so listing them here would install a
# toolchain and build both packages to verify nothing the change can
# reach.
if grep -Eq '^(daml/|scripts/fetch-dep\.sh$|versions\.env$|package\.json$|package-lock\.json$|multi-package\.yaml$|\.github/workflows/ci\.yml$)' <<<"$changed"; then
# Build and test inputs, including the smoke package the smoke
# step compiles and every script a step below runs. The
# files that merely name template ids are not listed: the check
# that reads them runs ahead of this gate and ignores it, so
# listing them here would install a toolchain and build both
# packages to verify nothing the change can reach. The install
# action is listed because this job runs it; release.yml is left
# out for that same reason, since no step in this job does.
if grep -Eq '^(daml/|consumer-smoke/|scripts/fetch-dep\.sh$|scripts/consumer-smoke\.sh$|scripts/release-notes\.sh$|\.github/actions/|versions\.env$|package\.json$|package-lock\.json$|multi-package\.yaml$|\.github/workflows/ci\.yml$)' <<<"$changed"; then
echo "run=true" | tee -a "$GITHUB_OUTPUT"
else
echo "run=false" | tee -a "$GITHUB_OUTPUT"
Expand All @@ -335,37 +469,17 @@ jobs:
distribution: temurin
java-version: '17'

# The published tarball is fetched by exact version and checked against a
# recorded digest instead of piping an installer into a shell. Pinning is
# also a correctness requirement, not only a supply-chain one: the
# installer's "latest" resolves to 3.5.5, while both daml.yaml files pin
# 3.4.11.
# The download, the digest that verifies it and the pin sweep live in the
# action, so release.yml runs the same three and neither workflow carries
# its own copy. It sweeps the pins again, which the ungated step above has
# already done here: that step exists to report before the toolchain and
# outside the gate, and this one is what gives release.yml the same check
# without a second copy of it.
- name: Install dpm
if: steps.scope.outputs.run == 'true'
run: |
set -euo pipefail
test "$(uname -m)" = "x86_64"
# DPM_SDK_VERSION is a third copy of a pin whose other two homes are
# the daml.yaml files. Assert rather than trust: bumping those and
# forgetting this one otherwise fails much later, or silently makes
# dpm download a second SDK.
for pkg in canton-token-forge canton-token-forge-test; do
pinned="$(awk '/^sdk-version:/ {print $2; exit}' "daml/${pkg}/daml.yaml")"
if [ "$pinned" != "$DPM_SDK_VERSION" ]; then
echo "daml/${pkg}/daml.yaml pins SDK ${pinned}, this workflow installs ${DPM_SDK_VERSION}" >&2
exit 1
fi
done
tarball="dpm-${DPM_SDK_VERSION}-linux-amd64.tar.gz"
url="https://artifactregistry.googleapis.com/download/v1/projects/da-images/locations/europe/repositories/public-generic/files/dpm-sdk:${DPM_SDK_VERSION}:${tarball}:download?alt=media"
curl -SLf --retry 3 --retry-all-errors --retry-delay 5 \
"$url" --output "${RUNNER_TEMP}/${tarball}"
echo "${DPM_TARBALL_SHA256} ${RUNNER_TEMP}/${tarball}" | sha256sum -c -
mkdir -p "${RUNNER_TEMP}/dpm-extracted"
tar xzf "${RUNNER_TEMP}/${tarball}" -C "${RUNNER_TEMP}/dpm-extracted" --strip-components 1
"${RUNNER_TEMP}/dpm-extracted/bin/dpm" bootstrap "${RUNNER_TEMP}/dpm-extracted"
rm -rf "${RUNNER_TEMP}/${tarball}" "${RUNNER_TEMP}/dpm-extracted"
echo "$HOME/.dpm/bin" >> "$GITHUB_PATH"
uses: ./.github/actions/install-dpm
with:
sdk-version: ${{ env.DPM_SDK_VERSION }}

- name: Report the installed SDK
if: steps.scope.outputs.run == 'true'
Expand Down Expand Up @@ -453,3 +567,39 @@ jobs:
- name: Test
if: steps.scope.outputs.run == 'true'
run: npm test

# canton-token-forge-test lists the Splice interface DARs separately,
# so it never exercises the artifact in isolation, and a change to what
# the production package bundles or exposes is otherwise green until a
# release is cut. The Test step above just built the DAR, so a rebuild
# here would only repeat that work. release.yml sets the same variable
# for a stronger reason: the bytes it publishes must be the ones its
# reproducibility check hashed.
- name: Consumer smoke test
if: steps.scope.outputs.run == 'true'
env:
SKIP_BUILD: '1'
run: npm run smoke

# The generator reads the smoke package and the built DAR and compares
# the two, so a change that leaves both compiling can still break the
# release body: a flag naming something the DAR stopped bundling, a
# bundled interface the snippet stopped naming, a block it can no longer
# find. Only the release workflow runs it otherwise, which would put its
# first automated run after the tag was already public. Under SKIP_BUILD
# it only reads, and it writes the body to stdout, so running it here
# costs almost nothing and leaves that body in the log to read.
#
# ALLOW_UNTAGGED because GITHUB_REF_NAME is a branch or a merge ref here,
# never a tag. It waives the refusal of a name that is not a tag, and so
# also the comparison against the checked-out commit, which only a real
# tag reaches: the body this step prints says "rebuild it at" whatever
# ref the run carries. Those two are what the step does not cover; the
# tag push
# in RUNBOOK.md's rehearsal is where it stays covered.
- name: Generate the release notes
if: steps.scope.outputs.run == 'true'
env:
SKIP_BUILD: '1'
ALLOW_UNTAGGED: '1'
run: bash scripts/release-notes.sh "${GITHUB_REF_NAME}"
Loading
Loading