Skip to content
Draft
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
14 changes: 14 additions & 0 deletions .github/actions/setup-nix/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: Set up nix
description: >
Install nix with the magic cache, keeping its FlakeHub lookup disabled.
Must run after actions/checkout so the cache can key off the repository
contents.
runs:
using: composite
steps:
- name: Install nix
uses: DeterminateSystems/determinate-nix-action@main
- name: Use nix cache
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
37 changes: 37 additions & 0 deletions .github/actions/verify-tag-version/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Verify tag version
description: >
Check that the pushed tag is the expected prefix followed by exactly the
version about to be published, refusing to publish on any mismatch.
inputs:
tag-prefix:
description: Expected tag prefix, e.g. payjoin-csharp-
required: true
version:
description: Version of the artifact or package about to be published
required: true
outputs:
version:
description: The version the tag calls for
value: ${{ steps.check.outputs.version }}
runs:
using: composite
steps:
- name: Compare tag against version
id: check
shell: bash
env:
TAG: ${{ github.ref_name }}
PREFIX: ${{ inputs.tag-prefix }}
VERSION: ${{ inputs.version }}
run: |
set -euo pipefail
if [[ $TAG != "$PREFIX"* ]]; then
echo "::error::tag $TAG does not start with $PREFIX; refusing to publish"
exit 1
fi
tag_version="${TAG#"$PREFIX"}"
if [[ $tag_version != "$VERSION" ]]; then
echo "::error::tag $TAG implies version $tag_version but the packed version is $VERSION; refusing to publish"
exit 1
fi
echo "version=$tag_version" >>"$GITHUB_OUTPUT"
32 changes: 8 additions & 24 deletions .github/workflows/crates-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@ jobs:
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Install nix
uses: DeterminateSystems/determinate-nix-action@main
- name: Use nix cache
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: Check the bump is consistent and publishable
env:
BASE_SHA: ${{ github.event.pull_request.base.sha }}
Expand All @@ -57,12 +53,8 @@ jobs:
fetch-depth: 0
- name: Fetch master
run: git fetch --no-tags origin +refs/heads/master:refs/remotes/origin/master
- name: Install nix
uses: DeterminateSystems/determinate-nix-action@main
- name: Use nix cache
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: Compute tag metadata
id: meta
env:
Expand Down Expand Up @@ -155,12 +147,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v6
- name: Install nix
uses: DeterminateSystems/determinate-nix-action@main
- name: Use nix cache
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: Download packaged crate
uses: actions/download-artifact@v4
with:
Expand Down Expand Up @@ -200,12 +188,8 @@ jobs:
steps:
- name: Checkout repo
uses: actions/checkout@v6
- name: Install nix
uses: DeterminateSystems/determinate-nix-action@main
- name: Use nix cache
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: Download packaged crate
uses: actions/download-artifact@v8
with:
Expand Down
85 changes: 28 additions & 57 deletions .github/workflows/csharp.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,8 @@ jobs:
uses: actions/checkout@v6
- name: "Use cache"
uses: Swatinem/rust-cache@v2
- name: "Install nix"
uses: DeterminateSystems/determinate-nix-action@main
- name: "Use nix cache"
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: "Build and test"
run: nix develop .#csharp -c ./payjoin-ffi/csharp/contrib/test.sh

Expand Down Expand Up @@ -276,8 +272,11 @@ jobs:
permissions:
id-token: write # OIDC: used by BOTH NuGet/login and attest-build-provenance
attestations: write # actions/attest-build-provenance writes the attestation
contents: read # checkout of the (already-packed) repo is not needed; read is the floor
contents: read # needed only to check out the in-repo verify-tag-version action
steps:
- name: Checkout
uses: actions/checkout@v6

- name: Download packed NuGet package
uses: actions/download-artifact@v4
with:
Expand All @@ -289,27 +288,28 @@ jobs:
with:
dotnet-version: "10.0.x"

- name: Verify tag matches packed artifact version
id: verify
- name: Locate packed artifact
id: locate
shell: bash
run: |
set -euo pipefail
# payjoin-csharp-0.24.0-preview.1 -> 0.24.0-preview.1
version="${GITHUB_REF_NAME#payjoin-csharp-}"
shopt -s nullglob
pkgs=(dist/*.nupkg)
if [ "${#pkgs[@]}" -ne 1 ]; then
echo "::error::expected exactly one .nupkg in dist/, found ${#pkgs[@]}: ${pkgs[*]:-none}"
exit 1
fi
expected="Payjoin.${version}.nupkg"
actual="$(basename "${pkgs[0]}")"
if [ "${actual}" != "${expected}" ]; then
echo "::error::tag ${GITHUB_REF_NAME} implies ${expected} but packed artifact is ${actual}; refusing to publish"
exit 1
fi
# Payjoin.0.24.0-preview.1.nupkg -> 0.24.0-preview.1
name="$(basename "${pkgs[0]}" .nupkg)"
echo "nupkg=${pkgs[0]}" >> "$GITHUB_OUTPUT"
echo "version=${version}" >> "$GITHUB_OUTPUT"
echo "version=${name#Payjoin.}" >> "$GITHUB_OUTPUT"

- name: Verify tag matches packed artifact version
id: verify
uses: ./.github/actions/verify-tag-version
with:
tag-prefix: payjoin-csharp-
version: ${{ steps.locate.outputs.version }}

- name: Attest build provenance (nupkg)
# Attesting the .nupkg covers every RID native lib inside it; a consumer
Expand All @@ -320,7 +320,7 @@ jobs:
# published unit.)
uses: actions/attest-build-provenance@v4
with:
subject-path: ${{ steps.verify.outputs.nupkg }}
subject-path: ${{ steps.locate.outputs.nupkg }}

- name: NuGet login (OIDC -> short-lived API key)
id: login
Expand All @@ -339,52 +339,23 @@ jobs:
# the tag would otherwise 409 on the already-published version and
# redden the whole run. With it, an already-present version is a
# no-op success and the run converges.
dotnet nuget push "${{ steps.verify.outputs.nupkg }}" \
dotnet nuget push "${{ steps.locate.outputs.nupkg }}" \
--api-key "${{ steps.login.outputs.NUGET_API_KEY }}" \
--source https://api.nuget.org/v3/index.json \
--no-symbols \
--skip-duplicate

github-release:
name: "Attach nupkg + SHA256SUMS to the GitHub release"
runs-on: ubuntu-latest
needs: [publish-nuget]
if: startsWith(github.ref, 'refs/tags/payjoin-csharp-')
permissions:
contents: write # create/update the Release for this tag and upload assets
steps:
- name: Download packed NuGet package
uses: actions/download-artifact@v4
with:
name: payjoin-csharp-nuget-package
path: dist

- name: Generate SHA256SUMS (nupkg + each native lib)
working-directory: dist
shell: bash
run: |
set -euo pipefail
# Hash the package itself.
sha256sum *.nupkg > SHA256SUMS
# Also hash each shipped native library extracted from inside the
# package, so a consumer can verify an individual .so/.dylib/.dll
# (paths are runtimes/<rid>/native/<lib>). Matches the tor/hwi pattern.
tmp="$(mktemp -d)"
unzip -q *.nupkg -d "$tmp" 'runtimes/*/native/*'
( cd "$tmp" && find runtimes -type f -print0 | sort -z | xargs -0 sha256sum ) >> SHA256SUMS
echo "----- SHA256SUMS -----"
cat SHA256SUMS

- name: Create / update GitHub release
uses: softprops/action-gh-release@v3
with:
files: |
dist/*.nupkg
dist/SHA256SUMS
fail_on_unmatched_files: true
draft: false
# Mark preview / rc tags as pre-releases on the Releases page.
prerelease: ${{ contains(github.ref_name, '-preview') || contains(github.ref_name, '-rc') }}
# Dan's GPG detached signature over SHA256SUMS is added out-of-band
# (locally, then uploaded as SHA256SUMS.asc) — his private key must not
# live on a runner. See README "GPG signature".
uses: ./.github/workflows/release-assets.yml
with:
artifact-pattern: payjoin-csharp-nuget-package
tag-prefix: payjoin-csharp-
# Also hash each shipped native library from inside the package, so a
# consumer can verify an individual .so/.dylib/.dll (paths are
# runtimes/<rid>/native/<lib>). Matches the tor/hwi pattern.
unzip-globs: runtimes/*/native/*
82 changes: 78 additions & 4 deletions .github/workflows/dart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,14 @@ on:
# change this workflow's environment.
- flake.nix
- flake.lock
# Publishing path. A tag push runs the build/test and archive-verification
# jobs at the tagged commit (no path filter applies to tags), then the
# tag-gated publish job below. Tag scheme: payjoin-dart-<pubspec version>,
# e.g. payjoin-dart-0.2.1+payjoin-1.0.0-rc.8 (the full version, including
# build metadata), matching the version-first payjoin-csharp-* convention.
push:
tags:
- "payjoin-dart-[0-9]*"

jobs:
build-dart-and-test:
Expand All @@ -25,9 +33,75 @@ jobs:
uses: actions/checkout@v6
- name: "Use cache"
uses: Swatinem/rust-cache@v2
- name: "Install nix"
uses: DeterminateSystems/determinate-nix-action@main
- name: "Use nix cache"
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: "Build and test"
run: nix develop .#dart -c bash ./payjoin-ffi/dart/contrib/test.sh

verify-pub-package:
# pub.dev ships source that consumers compile through hook/build.dart,
# so there is no artifact to pack or smoke test.
name: "Verify pub.dev package"
runs-on: ubuntu-26.04
steps:
- name: Checkout
uses: actions/checkout@v6
- name: "Use cache"
uses: Swatinem/rust-cache@v2
- 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

# ---------------------------------------------------------------------------
# PUBLISH PATH (tag-gated). Runs only for a payjoin-dart-* tag push, after
# build/test and the archive verification are green. The published unit is
# the pub.dev source archive, so there is no artifact to attach to a GitHub
# release afterwards.
# ---------------------------------------------------------------------------
publish-pub:
name: "Publish to pub.dev (automated publishing / OIDC)"
runs-on: ubuntu-26.04
needs: [build-dart-and-test, verify-pub-package]
if: startsWith(github.ref, 'refs/tags/payjoin-dart-')
# Pauses for a required reviewer before anything reaches the registry;
# the pub.dev automated-publishing config requires this environment.
environment: release
permissions:
id-token: write # OIDC: pub.dev automated publishing
contents: read
steps:
- name: Checkout
uses: actions/checkout@v6

- name: "Use cache"
uses: Swatinem/rust-cache@v2
- name: Set up nix
uses: ./.github/actions/setup-nix

- name: Read pubspec version
id: pubspec
shell: bash
run: |
set -euo pipefail
version="$(sed -n 's/^version: *//p' payjoin-ffi/dart/pubspec.yaml)"
if [ -z "$version" ]; then
echo "::error::could not read version from pubspec.yaml"
exit 1
fi
echo "version=$version" >>"$GITHUB_OUTPUT"

- name: Verify tag matches pubspec version
uses: ./.github/actions/verify-tag-version
with:
tag-prefix: payjoin-dart-
version: ${{ steps.pubspec.outputs.version }}

- name: Prepare the package
run: nix develop .#dart -c ./payjoin-ffi/dart/contrib/prepare-publish.sh

- name: Publish to pub.dev
# dart pub exchanges the job's OIDC token for short-lived pub.dev
# credentials; there is no long-lived token anywhere in this
# workflow. --force skips the interactive confirmation.
run: nix develop .#dart -c bash -c 'cd payjoin-ffi/dart && dart pub publish --force'
8 changes: 2 additions & 6 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@ jobs:
steps:
- name: "Checkout repo"
uses: actions/checkout@v6
- name: "Install nix"
uses: DeterminateSystems/determinate-nix-action@main
- name: "Use nix cache"
uses: DeterminateSystems/magic-nix-cache-action@main
with:
use-flakehub: false
- name: Set up nix
uses: ./.github/actions/setup-nix
- name: Run treefmt
run: |
set -eo pipefail
Expand Down
Loading
Loading