Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 9 additions & 1 deletion .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,15 @@ jobs:
- name: Set up nix
uses: $/.github/actions/setup-nix
- name: Generate production bindings and dry-run publish
run: nix develop .#dart -c ./payjoin-ffi/dart/contrib/prepare-publish.sh "$RUNNER_TEMP/payjoin-pub"
run: |
# Pull requests may change payjoin or payjoin-mailroom without a
# version bump, so they stage those crates from the checkout.
# Releases stage against crates.io, as consumers build them.
flags=()
if [[ $GITHUB_EVENT_NAME == pull_request ]]; then
flags+=(--core-from-revision)
fi
nix develop .#dart -c ./payjoin-ffi/dart/contrib/prepare-publish.sh "${flags[@]}" "$RUNNER_TEMP/payjoin-pub"
# The release workflow publishes this exact stage, so it is archived
# rather than regenerated in the publish job.
- name: Archive the staged package
Expand Down
11 changes: 6 additions & 5 deletions payjoin-ffi/dart/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,11 +82,12 @@ validates the archive with a publish dry run
is seeded from `Cargo-recent.lock` and resolved against that revision,
so consumers build the versions CI tested. A dependency fix reaches
Dart consumers through `Cargo-recent.lock` and a new release. Staging
fetches the pinned commit from GitHub, so it must be pushed. When a
`payjoin` or `payjoin-mailroom` version that `payjoin-ffi` or
`payjoin-test-utils` requires is not on crates.io yet, staging takes
it from the same revision and writes an `UNPUBLISHED_CORE` marker,
which `contrib/publish.sh` refuses. Both the publish dry run and
fetches the pinned commit from GitHub, so it must be pushed. The
`payjoin` and `payjoin-mailroom` crates come from crates.io, except
with `--core-from-revision`, which pull requests use since they may
change those crates without a version bump. That option takes them
from the same revision and writes an `UNPUBLISHED_CORE` marker, which
`contrib/publish.sh` refuses. Both the publish dry run and
publication use the staged package. For local checks:

```shell
Expand Down
60 changes: 24 additions & 36 deletions payjoin-ffi/dart/contrib/prepare-publish.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
#!/usr/bin/env bash
set -euo pipefail
core_from_revision=false
if [[ ${1:-} == --core-from-revision ]]; then
core_from_revision=true
shift
fi
[ "$#" -eq 1 ] || {
echo "usage: prepare-publish.sh <new-package-dir>" >&2
echo "usage: prepare-publish.sh [--core-from-revision] <new-package-dir>" >&2
exit 1
}
# Resolve before changing directories; the destination must not exist.
Expand Down Expand Up @@ -39,48 +44,31 @@ grep -Fq "rev = \"$revision\"" "$stage/native/Cargo.toml" || {

# payjoin-ffi and payjoin-test-utils come from the pinned revision, but the
# release crates they require, payjoin and payjoin-mailroom, come from
# crates.io. Between a version bump of one of those and its crates.io
# release, the lock below could not resolve it. Take such a crate from the
# pinned revision instead so pull requests can still stage, and leave a
# crates.io. A pull request can change those crates without a version bump,
# so its payjoin-ffi may not build against what crates.io has. With
# --core-from-revision, take them from the pinned revision too, and leave a
# marker that publish.sh refuses: a published package must build against
# crates its consumers can get from crates.io.
source "$REPO_ROOT/contrib/release/crates.sh"
# crates.io answers 404 for a version it does not have. Any other failure,
# such as a rate limit or an outage, must stop here rather than read as
# unpublished, or a release run would stage a package publish.sh refuses.
crates_io_status() {
curl -sL --retry 3 -o /dev/null -w '%{http_code}' \
-H "User-Agent: rust-payjoin release tooling" \
"https://crates.io/api/v1/crates/$1/$2" || true
}
siblings="$(sibling_deps payjoin-ffi && sibling_deps payjoin-test-utils)"
[[ $siblings == *payjoin$'\t'* ]] || {
echo "Could not read the payjoin version payjoin-ffi requires" >&2
exit 1
}
while IFS=$'\t' read -r dep req; do
version="${req#^}"
version="${version#=}"
status="$(crates_io_status "$dep" "$version")"
case $status in
200) continue ;;
404) ;;
*)
echo "Could not check $dep $version on crates.io (HTTP $status)" >&2
exit 1
;;
esac
echo "==> $dep $version is not on crates.io; staging it from $revision"
cat >>"$stage/native/Cargo.toml" <<EOF
if [[ $core_from_revision == true ]]; then
source "$REPO_ROOT/contrib/release/crates.sh"
siblings="$(sibling_deps payjoin-ffi && sibling_deps payjoin-test-utils)"
[[ $siblings == *payjoin$'\t'* ]] || {
echo "Could not read the payjoin version payjoin-ffi requires" >&2
exit 1
}
while IFS=$'\t' read -r dep _; do
echo "==> Staging $dep from $revision"
cat >>"$stage/native/Cargo.toml" <<EOF
# Added by prepare-publish.sh: $dep $version is not on crates.io yet.
# Added by prepare-publish.sh --core-from-revision.
[patch.crates-io.$dep]
git = "https://github.com/payjoin/rust-payjoin.git"
rev = "$revision"
EOF
printf '%s %s comes from %s, not crates.io\n' "$dep" "$version" \
"$revision" >>"$stage/UNPUBLISHED_CORE"
done < <(sort -u <<<"$siblings")
printf '%s comes from %s, not crates.io\n' "$dep" "$revision" \
>>"$stage/UNPUBLISHED_CORE"
done < <(sort -u <<<"$siblings")
fi

# Ship the dependency graph this release was tested against; hook/build.dart
# builds it with --locked. Seeding from the maintained lockfile keeps every
Expand Down
Loading