From 58ca3e1a74ee646c1cbb4c8ad0b9cfe91964211f Mon Sep 17 00:00:00 2001 From: Benalleng Date: Wed, 16 Sep 2026 13:44:28 -0400 Subject: [PATCH 1/4] Prepare CI jobs for zizmor checks Add on own edit checks for workflows that may have impacts on PR success Fix smoke to allow CI to pass This also adds a specific lockfile `smoke/package.json` so the CI job does not install anything ad-hoc which would violate the zizmor checks. --- .github/actions/setup-nix/action.yml | 4 +- .github/workflows/bindings-release.yml | 85 +++++++++++-------- .github/workflows/changelog-check.yml | 3 +- .github/workflows/crates-release.yml | 67 +++++++++------ .github/workflows/cron-directory-monitor.yml | 11 ++- .github/workflows/cron-weekly-mutants.yml | 8 +- .github/workflows/csharp.yml | 76 +++++++++++------ .github/workflows/dart.yml | 35 +++++--- .github/workflows/flake-check.yml | 9 +- .github/workflows/flake-maintenance.yml | 21 +++-- .github/workflows/format.yml | 9 +- .github/workflows/javascript.yml | 62 +++++++++----- .github/workflows/kotlin.yml | 23 ++--- .github/workflows/lock-maintenance.yml | 14 ++- .github/workflows/nightly-maintenance.yml | 23 +++-- .github/workflows/python.yml | 39 +++++---- .github/workflows/release-image.yml | 19 +++-- .github/workflows/rust.yml | 83 ++++++++++++------ .github/workflows/standup-compile.yml | 12 ++- .github/workflows/standup-on-comment.yml | 12 ++- .github/workflows/standup-prompt.yml | 12 ++- payjoin-ffi/javascript/smoke/.gitignore | 2 + .../javascript/smoke/package-lock.json | 38 +++++++++ payjoin-ffi/javascript/smoke/package.json | 9 ++ 24 files changed, 459 insertions(+), 217 deletions(-) create mode 100644 payjoin-ffi/javascript/smoke/.gitignore create mode 100644 payjoin-ffi/javascript/smoke/package-lock.json create mode 100644 payjoin-ffi/javascript/smoke/package.json diff --git a/.github/actions/setup-nix/action.yml b/.github/actions/setup-nix/action.yml index c1c3e5bf1..62094a15f 100644 --- a/.github/actions/setup-nix/action.yml +++ b/.github/actions/setup-nix/action.yml @@ -7,9 +7,9 @@ runs: using: composite steps: - name: Install nix - uses: DeterminateSystems/determinate-nix-action@main + uses: DeterminateSystems/determinate-nix-action@fd3eb131b9b46cc1dd978a7c0ba3fce79dd7d3eb # v3.9.1 - name: Use nix cache - uses: nix-community/cache-nix-action@v7 + uses: nix-community/cache-nix-action@7df957e333c1e5da7721f60227dbba6d06080569 # v7.0.2 with: primary-key: nix-${{ runner.os }}-${{ github.job }}-${{ hashFiles('flake.nix', 'flake.lock') }} restore-prefixes-first-match: nix-${{ runner.os }}-${{ github.job }}- diff --git a/.github/workflows/bindings-release.yml b/.github/workflows/bindings-release.yml index 97c477b45..f15ba07cd 100644 --- a/.github/workflows/bindings-release.yml +++ b/.github/workflows/bindings-release.yml @@ -33,13 +33,14 @@ jobs: prerelease: ${{ steps.meta.outputs.prerelease }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: fetch-depth: 0 + persist-credentials: false - name: Fetch master run: git fetch --no-tags origin +refs/heads/master:refs/remotes/origin/master - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Verify tag hygiene env: TAG: ${{ github.ref_name }} @@ -70,19 +71,19 @@ jobs: python: needs: verify-tag - uses: ./.github/workflows/python.yml + uses: $/.github/workflows/python.yml javascript: needs: verify-tag - uses: ./.github/workflows/javascript.yml + uses: $/.github/workflows/javascript.yml csharp: needs: verify-tag - uses: ./.github/workflows/csharp.yml + uses: $/.github/workflows/csharp.yml dart: needs: verify-tag - uses: ./.github/workflows/dart.yml + uses: $/.github/workflows/dart.yml kotlin: needs: verify-tag - uses: ./.github/workflows/kotlin.yml + uses: $/.github/workflows/kotlin.yml publish-python: name: Publish to PyPI @@ -94,7 +95,7 @@ jobs: attestations: write # actions/attest-build-provenance writes the attestation steps: - name: Download wheels - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: pattern: payjoin-python-wheel-* merge-multiple: true @@ -110,11 +111,11 @@ jobs: fi - name: Attest build provenance # A consumer runs: gh attestation verify .whl -R payjoin/rust-payjoin - uses: actions/attest-build-provenance@v4 + uses: actions/attest-build-provenance@4d101475d8b20a2381f78447822ac1eab6504dd8 # v4.2.2 with: subject-path: dist/*.whl - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@release/v1 + uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2 with: packages-dir: dist @@ -128,19 +129,16 @@ jobs: attestations: write # actions/attest writes the attestation steps: - name: Download npm package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: payjoin-javascript-npm-package path: dist - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: - node-version: "24" + node-version: "24" # ships npm 11, needed for OIDC trusted publishing registry-url: https://registry.npmjs.org - - name: Update npm - run: | - npm install -g npm@11 - npm --version + package-manager-cache: false # publishing workflow: cache would be poisonable - name: Locate the tarball id: locate run: | @@ -154,7 +152,7 @@ jobs: echo "tarball=${pkgs[0]}" >>"$GITHUB_OUTPUT" - name: Attest build provenance # A consumer runs: gh attestation verify .tgz -R payjoin/rust-payjoin - uses: actions/attest@v4 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-path: ${{ steps.locate.outputs.tarball }} - name: Publish to npmjs.com @@ -175,12 +173,12 @@ jobs: attestations: write # actions/attest writes the attestation steps: - name: Download NuGet package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: payjoin-csharp-nuget-package path: dist - name: Install .NET 10 SDK - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 with: dotnet-version: "10.0.x" - name: Locate the package @@ -197,12 +195,12 @@ jobs: - name: Attest build provenance # Attesting the .nupkg covers every RID native lib inside it; a consumer # runs: gh attestation verify .nupkg -R payjoin/rust-payjoin - uses: actions/attest@v4 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-path: ${{ steps.locate.outputs.nupkg }} - name: NuGet login (OIDC -> short-lived API key) id: login - uses: NuGet/login@v1 + uses: NuGet/login@8d196754b4036150537f80ac539e15c2f1028841 # v1.2.0 with: user: ${{ secrets.NUGET_USER }} - name: Push to nuget.org @@ -226,11 +224,13 @@ jobs: contents: read steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Download the staged package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: payjoin-dart-pub-package path: dist @@ -258,9 +258,11 @@ jobs: VERSION: ${{ needs.verify-tag.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false - name: Download every package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: pattern: payjoin-* merge-multiple: true @@ -297,11 +299,24 @@ jobs: echo "CHANGELOG_EOF" } >>"$GITHUB_OUTPUT" - name: Create release - uses: softprops/action-gh-release@v3 - with: - tag_name: ${{ github.ref_name }} - name: Release ${{ github.ref_name }} - body: ${{ steps.changelog.outputs.body }} - prerelease: ${{ needs.verify-tag.outputs.prerelease }} - fail_on_unmatched_files: true - files: dist/* + env: + GH_TOKEN: ${{ github.token }} + TAG: ${{ github.ref_name }} + PRERELEASE: ${{ needs.verify-tag.outputs.prerelease }} + BODY: ${{ steps.changelog.outputs.body }} + run: | + set -euo pipefail + notes="$RUNNER_TEMP/release-notes.md" + printf '%s\n' "$BODY" >"$notes" + args=(--title "Release $TAG" --notes-file "$notes") + if [ "$PRERELEASE" = "true" ]; then + args+=(--prerelease) + fi + # A re-run after a partial failure edits the release that already + # exists and re-uploads its assets instead of failing. + if gh release view "$TAG" >/dev/null 2>&1; then + gh release edit "$TAG" "${args[@]}" + gh release upload "$TAG" dist/* --clobber + else + gh release create "$TAG" "${args[@]}" dist/* + fi diff --git a/.github/workflows/changelog-check.yml b/.github/workflows/changelog-check.yml index 0a502ac04..2bdb7387b 100644 --- a/.github/workflows/changelog-check.yml +++ b/.github/workflows/changelog-check.yml @@ -19,8 +19,9 @@ jobs: if: "${{ !contains(github.event.pull_request.labels.*.name, 'changelog: none') }}" runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: + persist-credentials: false # unneeded: no git auth beyond checkout fetch-depth: 0 - name: Require a changelog line for each changed crate env: diff --git a/.github/workflows/crates-release.yml b/.github/workflows/crates-release.yml index 88afc473a..3a540fdb0 100644 --- a/.github/workflows/crates-release.yml +++ b/.github/workflows/crates-release.yml @@ -15,6 +15,7 @@ on: - payjoin-cli/Cargo.toml - payjoin-mailroom/Cargo.toml - payjoin-ffi/Cargo.toml + - .github/workflows/crates-release.yml push: tags: - payjoin-[0-9]* @@ -31,11 +32,12 @@ jobs: runs-on: ubuntu-26.04 steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: + persist-credentials: false # unneeded: no git auth beyond checkout fetch-depth: 0 - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Check the bump is consistent and publishable env: BASE_SHA: ${{ github.event.pull_request.base.sha }} @@ -51,13 +53,14 @@ jobs: prerelease: ${{ steps.meta.outputs.prerelease }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: + persist-credentials: false # unneeded: no git auth beyond checkout fetch-depth: 0 - name: Fetch master run: git fetch --no-tags origin +refs/heads/master:refs/remotes/origin/master - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Compute tag metadata id: meta env: @@ -88,7 +91,7 @@ jobs: # tagged commit. Scoping by regexp avoids waiting on this workflow's # own downstream publish jobs, which would deadlock. - name: Wait for test, lint, and format checks - uses: lewagon/wait-on-check-action@v1.9.0 + uses: lewagon/wait-on-check-action@2271c86c146b96545b4e871b855e10ffa6f50773 # v1.9.0 with: ref: ${{ github.sha }} check-regexp: ^(Test|Lint|Format) @@ -111,28 +114,34 @@ jobs: VERSION: ${{ needs.verify-tag.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install toolchain - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: stable - name: Use cache - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Prepare lockfile run: cp Cargo-recent.lock Cargo.lock - name: Package the crate run: cargo package --locked -p "$CRATE" - name: Attest build provenance - uses: actions/attest@v4 + uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2 with: subject-path: target/package/${{ needs.verify-tag.outputs.crate }}-${{ needs.verify-tag.outputs.version }}.crate - name: Authenticate to crates.io id: auth - uses: rust-lang/crates-io-auth-action@v1 + uses: rust-lang/crates-io-auth-action@c6f97d42243bad5fab37ca0427f495c86d5b1a18 # v1.0.5 - name: Publish to crates.io env: CARGO_REGISTRY_TOKEN: ${{ steps.auth.outputs.token }} run: cargo publish --locked -p "$CRATE" - name: Upload packaged crate - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: crate path: target/package/${{ needs.verify-tag.outputs.crate }}-${{ needs.verify-tag.outputs.version }}.crate @@ -149,11 +158,13 @@ jobs: VERSION: ${{ needs.verify-tag.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Download packaged crate - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: crate path: dist @@ -169,16 +180,16 @@ jobs: echo "CHANGELOG_EOF" } >>"$GITHUB_OUTPUT" - name: Create release - uses: softprops/action-gh-release@v3 - with: - tag_name: ${{ github.ref_name }} - name: Release ${{ github.ref_name }} - body: ${{ steps.changelog.outputs.body }} - generate_release_notes: true - prerelease: ${{ needs.verify-tag.outputs.prerelease }} - files: | - dist/*.crate - dist/SHA256SUMS + env: + GH_TOKEN: ${{ github.token }} + PRERELEASE: ${{ needs.verify-tag.outputs.prerelease }} + CHANGELOG: ${{ steps.changelog.outputs.body }} + run: | + args=(dist/*.crate dist/SHA256SUMS --title "Release ${GITHUB_REF_NAME}" --generate-notes --notes "$CHANGELOG") + if [[ "${PRERELEASE}" == "true" ]]; then + args+=(--prerelease) + fi + gh release create "${GITHUB_REF_NAME}" "${args[@]}" verify-published: name: Verify publication @@ -190,11 +201,13 @@ jobs: VERSION: ${{ needs.verify-tag.outputs.version }} steps: - name: Checkout repo - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Download packaged crate - uses: actions/download-artifact@v8 + uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: crate path: dist diff --git a/.github/workflows/cron-directory-monitor.yml b/.github/workflows/cron-directory-monitor.yml index 05ed3e3c8..f45f4c387 100644 --- a/.github/workflows/cron-directory-monitor.yml +++ b/.github/workflows/cron-directory-monitor.yml @@ -1,11 +1,20 @@ name: Payjoin directory health check on: + pull_request: + paths: + - .github/workflows/cron-directory-monitor.yml schedule: - cron: "9,23,38,53 * * * *" # Runs 4 times per hour offset from the high traffic quarters that may delay or cancel a run from occuring + +permissions: + contents: read + jobs: health-check: runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Check /health endpoint run: cd payjoin-mailroom && bash contrib/health-check.sh diff --git a/.github/workflows/cron-weekly-mutants.yml b/.github/workflows/cron-weekly-mutants.yml index 7354d1cbf..616241de7 100644 --- a/.github/workflows/cron-weekly-mutants.yml +++ b/.github/workflows/cron-weekly-mutants.yml @@ -9,12 +9,14 @@ jobs: permissions: issues: write steps: - - uses: actions/checkout@v6 - - uses: taiki-e/install-action@v2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: taiki-e/install-action@26e9283f268b880168bdbd2c545dfcd60ec2c6ab # v2.87.13 with: tool: cargo-mutants@27.1.0 - run: cargo mutants --in-place --no-shuffle - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 if: always() with: name: mutants.out diff --git a/.github/workflows/csharp.yml b/.github/workflows/csharp.yml index 418775d9f..29a98ae05 100644 --- a/.github/workflows/csharp.yml +++ b/.github/workflows/csharp.yml @@ -1,10 +1,6 @@ name: Build and Test CSharp on: - workflow_run: - workflows: ["Flake maintenance"] - types: [requested] - branches: - - "update_flake_lock_action" + workflow_call: pull_request: paths: - payjoin-ffi/** @@ -12,7 +8,9 @@ on: # the flake change this workflow's environment. - flake.nix - flake.lock - workflow_call: + +permissions: + contents: read jobs: build-csharp-and-test-unix: @@ -25,15 +23,20 @@ jobs: RUSTUP_TOOLCHAIN: 1.85.0 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install Rust 1.85.0" - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: msrv-workspace - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Build and test" run: nix develop .#csharp -c ./payjoin-ffi/csharp/contrib/test.sh @@ -47,15 +50,21 @@ jobs: working-directory: payjoin-ffi/csharp steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Rust 1.85.0 - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: Use cache - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Install .NET 10 SDK - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 with: dotnet-version: "10.0.x" @@ -107,15 +116,20 @@ jobs: target: x86_64-pc-windows-msvc steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Rust 1.85.0 - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 with: + toolchain: 1.85.0 targets: ${{ matrix.target }} - name: Use cache - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Install cross toolchain # Version- and hash-pinned: these tools produce the shipped binaries. @@ -150,7 +164,7 @@ jobs: PAYJOIN_FFI_CROSS=1 PAYJOIN_FFI_RID=${{ matrix.rid }} bash ./scripts/build_nuget_native.sh - name: Upload NuGet native asset - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: ${{ matrix.rid }} path: payjoin-ffi/csharp/artifacts/runtimes/${{ matrix.rid }}/native/* @@ -169,21 +183,27 @@ jobs: working-directory: payjoin-ffi/csharp steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Rust 1.85.0 - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: Use cache - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Install .NET 10 SDK - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 with: dotnet-version: "10.0.x" - name: Download native assets - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: path: payjoin-ffi/csharp/artifacts/downloaded @@ -202,7 +222,7 @@ jobs: run: dotnet pack Payjoin.csproj --configuration Release --output artifacts/packages - name: Upload NuGet package - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: payjoin-csharp-nuget-package path: payjoin-ffi/csharp/artifacts/packages/*.nupkg @@ -232,15 +252,17 @@ jobs: rid: win-x64 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install .NET 10 SDK - uses: actions/setup-dotnet@v4 + uses: actions/setup-dotnet@67a3573c9a986a3f9c594539f4ab511d57bb3ce9 # v4.3.1 with: dotnet-version: "10.0.x" - name: Download NuGet package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: payjoin-csharp-nuget-package path: payjoin-ffi/csharp/artifacts/packages diff --git a/.github/workflows/dart.yml b/.github/workflows/dart.yml index 9ea38d7b0..c6c4d6b43 100644 --- a/.github/workflows/dart.yml +++ b/.github/workflows/dart.yml @@ -1,10 +1,6 @@ name: Build and Test Dart on: - workflow_run: - workflows: ["Flake maintenance"] - types: [requested] - branches: - - "update_flake_lock_action" + workflow_call: pull_request: paths: - payjoin-ffi/** @@ -12,7 +8,9 @@ on: # change this workflow's environment. - flake.nix - flake.lock - workflow_call: + +permissions: + contents: read jobs: build-dart-and-test: @@ -25,15 +23,20 @@ jobs: RUSTUP_TOOLCHAIN: 1.85.0 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install Rust 1.85.0" - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: msrv-workspace - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Build and test" run: nix develop .#dart -c bash ./payjoin-ffi/dart/contrib/test.sh @@ -42,11 +45,15 @@ jobs: runs-on: ubuntu-26.04 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Set up nix - uses: ./.github/actions/setup-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" # The release workflow publishes this exact stage, so it is archived @@ -54,7 +61,7 @@ jobs: - name: Archive the staged package run: tar -czf "$RUNNER_TEMP/payjoin-dart.tar.gz" -C "$RUNNER_TEMP/payjoin-pub" . - name: Upload the staged package - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: payjoin-dart-pub-package path: ${{ runner.temp }}/payjoin-dart.tar.gz diff --git a/.github/workflows/flake-check.yml b/.github/workflows/flake-check.yml index 6509ef8d7..1eface868 100644 --- a/.github/workflows/flake-check.yml +++ b/.github/workflows/flake-check.yml @@ -7,6 +7,9 @@ on: paths-ignore: - "flake.lock" +permissions: + contents: read + jobs: flake-check: runs-on: ubuntu-26.04 @@ -19,10 +22,12 @@ jobs: - maintenance steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main + uses: DeterminateSystems/nix-installer-action@3138316df39ed29be04236d7ffc686fa525866aa # v23 - name: Run full flake check run: nix build .#checks.x86_64-linux.${{ matrix.checks }} diff --git a/.github/workflows/flake-maintenance.yml b/.github/workflows/flake-maintenance.yml index a752abc6f..3f4019697 100644 --- a/.github/workflows/flake-maintenance.yml +++ b/.github/workflows/flake-maintenance.yml @@ -5,6 +5,9 @@ on: - cron: "0 11 * * 1" # weekly at 14:00 UTC workflow_dispatch: +permissions: + contents: read + jobs: validate-lock-file: runs-on: ubuntu-26.04 @@ -16,10 +19,12 @@ jobs: - nightly steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main + uses: DeterminateSystems/nix-installer-action@3138316df39ed29be04236d7ffc686fa525866aa # v23 - name: Validate recreated lockfile run: nix build .#checks.x86_64-linux.${{ matrix.checks }} -L --recreate-lock-file --no-write-lock-file @@ -32,20 +37,24 @@ jobs: pull-requests: write steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main + uses: DeterminateSystems/nix-installer-action@3138316df39ed29be04236d7ffc686fa525866aa # v23 - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write - name: Update flake.lock - uses: DeterminateSystems/update-flake-lock@main + uses: DeterminateSystems/update-flake-lock@da03c0f078bc4b2c37ee4f7e072d34bf8f188bb3 # v29 with: pr-title: "chore: update flake.lock" commit-msg: "chore: update flake.lock" diff --git a/.github/workflows/format.yml b/.github/workflows/format.yml index e99777e93..63492bdce 100644 --- a/.github/workflows/format.yml +++ b/.github/workflows/format.yml @@ -2,14 +2,19 @@ name: Formatting on: [push, pull_request] +permissions: + contents: read + jobs: Format: runs-on: ubuntu-26.04 steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Run treefmt run: | set -eo pipefail diff --git a/.github/workflows/javascript.yml b/.github/workflows/javascript.yml index 2d5ff13b4..b6b20328d 100644 --- a/.github/workflows/javascript.yml +++ b/.github/workflows/javascript.yml @@ -1,10 +1,6 @@ name: Build and Test JavaScript on: - workflow_run: - workflows: ["Flake maintenance"] - types: [requested] - branches: - - "update_flake_lock_action" + workflow_call: pull_request: paths: - payjoin-ffi/** @@ -12,7 +8,9 @@ on: # change this workflow's environment. - flake.nix - flake.lock - workflow_call: + +permissions: + contents: read jobs: build-js-and-test: @@ -25,15 +23,20 @@ jobs: RUSTUP_TOOLCHAIN: 1.85.0 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install Rust 1.85.0" - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: msrv-workspace - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Build and test" run: nix develop .#javascript -c ./payjoin-ffi/javascript/contrib/test.sh @@ -44,15 +47,19 @@ jobs: runs-on: ubuntu-26.04 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Build and pack run: nix develop .#javascript -c ./payjoin-ffi/javascript/contrib/pack.sh - name: Upload npm package - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: payjoin-javascript-npm-package path: payjoin-ffi/javascript/artifacts/*.tgz @@ -66,22 +73,37 @@ jobs: matrix: os: [ubuntu-26.04, macos-latest] steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Download npm package - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: name: payjoin-javascript-npm-package - path: pkg + path: payjoin-ffi/javascript/smoke/pkg - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0 with: node-version: "24" + package-manager-cache: false - name: Install and exercise the packed package shell: bash run: | set -euo pipefail - mkdir smoke && cd smoke - npm init -y >/dev/null - npm install ../pkg/payjoin-*.tgz + cd payjoin-ffi/javascript/smoke + # The lockfile pins a stable tarball path so the artifact's + # version-named file must be renamed to match it. + shopt -s nullglob + tarballs=(pkg/payjoin-*.tgz) + if [ "${#tarballs[@]}" -ne 1 ]; then + echo "::error::expected exactly one .tgz in pkg/, found ${#tarballs[@]}: ${tarballs[*]:-none}" + exit 1 + fi + mv "${tarballs[0]}" pkg/payjoin.tgz + # Installs payjoin and its dependencies from the committed + # lockfile, so nothing is ever installed ad-hoc. + npm ci node --input-type=module -e ' import { payjoin, uniffiInitAsync } from "payjoin"; await uniffiInitAsync(); diff --git a/.github/workflows/kotlin.yml b/.github/workflows/kotlin.yml index cad8b004e..2c049034d 100644 --- a/.github/workflows/kotlin.yml +++ b/.github/workflows/kotlin.yml @@ -1,10 +1,6 @@ name: Build and Test Kotlin on: - workflow_run: - workflows: ["Flake maintenance"] - types: [requested] - branches: - - "update_flake_lock_action" + workflow_call: pull_request: paths: - payjoin-ffi/** @@ -13,7 +9,9 @@ on: - flake.nix - flake.lock - .github/workflows/kotlin.yml - workflow_call: + +permissions: + contents: read jobs: build-kotlin-and-test: @@ -26,15 +24,20 @@ jobs: RUSTUP_TOOLCHAIN: 1.85.0 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install Rust 1.85.0" - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: msrv-workspace - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Build and test" run: nix develop .#kotlin -c bash ./payjoin-ffi/kotlin/contrib/test.sh - name: "Compile production bindings" diff --git a/.github/workflows/lock-maintenance.yml b/.github/workflows/lock-maintenance.yml index b3602bfb5..14fb08ed9 100644 --- a/.github/workflows/lock-maintenance.yml +++ b/.github/workflows/lock-maintenance.yml @@ -13,16 +13,22 @@ jobs: contents: write pull-requests: write steps: - - uses: actions/checkout@v6 - - uses: dtolnay/rust-toolchain@nightly + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: nightly - run: bash contrib/update-lock-files.sh - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} - - uses: peter-evans/create-pull-request@v7 + permission-contents: write + permission-pull-requests: write + - uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 with: title: "chore: update cargo.lock" commit-message: "chore: update cargo.lock" diff --git a/.github/workflows/nightly-maintenance.yml b/.github/workflows/nightly-maintenance.yml index 09e5b76f2..4ca8487ed 100644 --- a/.github/workflows/nightly-maintenance.yml +++ b/.github/workflows/nightly-maintenance.yml @@ -5,14 +5,19 @@ on: - cron: "0 11 * * 2" # weekly Tuesday, after Monday's flake maintenance workflow_dispatch: +permissions: + contents: read + jobs: validate-toolchain: runs-on: ubuntu-26.04 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Update nightly toolchain pin run: ./contrib/bump-nightly.sh - name: Validate pinned toolchain @@ -24,21 +29,27 @@ jobs: permissions: contents: write pull-requests: write + workflows: write steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Update nightly toolchain pin run: ./contrib/bump-nightly.sh - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-contents: write + permission-pull-requests: write + permission-workflows: write - name: Create pull request - uses: peter-evans/create-pull-request@v7 + uses: peter-evans/create-pull-request@22a9089034f40e5a961c8808d113e2c98fb63676 # v7.0.11 with: title: "chore: update nightly toolchain pin" commit-message: "chore: update nightly toolchain pin" diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml index 537dd6957..6874c3dc5 100644 --- a/.github/workflows/python.yml +++ b/.github/workflows/python.yml @@ -1,10 +1,6 @@ name: Build and Test Python on: - workflow_run: - workflows: ["Flake maintenance"] - types: [requested] - branches: - - "update_flake_lock_action" + workflow_call: pull_request: paths: - payjoin-ffi/** @@ -12,7 +8,9 @@ on: # change this workflow's environment. - flake.nix - flake.lock - workflow_call: + +permissions: + contents: read jobs: build-python-and-test: @@ -25,15 +23,20 @@ jobs: RUSTUP_TOOLCHAIN: 1.85.0 steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install Rust 1.85.0" - uses: dtolnay/rust-toolchain@1.85.0 + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: 1.85.0 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: msrv-workspace - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Build and test" run: nix develop .#python --command bash ./payjoin-ffi/python/contrib/test.sh @@ -50,17 +53,21 @@ jobs: platform: [linux-x64, macos-universal2] steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: Build the wheel run: nix develop .#python --command bash ./payjoin-ffi/python/contrib/build-wheel.sh env: PAYJOIN_WHEEL_PLATFORM: ${{ matrix.platform }} - name: Upload wheel - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: payjoin-python-wheel-${{ matrix.platform }} path: payjoin-ffi/python/dist/*.whl @@ -75,13 +82,13 @@ jobs: os: [ubuntu-26.04, macos-latest, macos-15-intel] steps: - name: Download wheels - uses: actions/download-artifact@v4 + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 with: pattern: payjoin-python-wheel-* merge-multiple: true path: dist - name: Install Python - uses: actions/setup-python@v5 + uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: # Deliberately not the version the wheel was built with: the # wheels are tagged py3-none (the bindings load the library diff --git a/.github/workflows/release-image.yml b/.github/workflows/release-image.yml index dfb08afe6..e50794750 100644 --- a/.github/workflows/release-image.yml +++ b/.github/workflows/release-image.yml @@ -4,6 +4,7 @@ on: pull_request: paths: - payjoin-mailroom/** + - .github/workflows/release-image.yml push: tags: - payjoin-mailroom-[0-9]* @@ -21,13 +22,15 @@ jobs: packages: write steps: - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main + uses: DeterminateSystems/nix-installer-action@3138316df39ed29be04236d7ffc686fa525866aa # v23 - name: Log in to Docker Hub - uses: docker/login-action@v4 + uses: docker/login-action@dbcb813823bdd20940b903addbd779551569679f # v4.6.0 with: username: ${{ github.repository_owner }} password: ${{ secrets.PAYJOIN_DOCKER_RW }} @@ -51,17 +54,19 @@ jobs: packages: write steps: - name: Wait for other workflows - uses: lewagon/wait-on-check-action@v1.5.0 + uses: lewagon/wait-on-check-action@74049309dfeff245fe8009a0137eacf28136cb3c # v1.5.0 with: ref: ${{ github.event.pull_request.head.sha }} running-workflow-name: "Build and upload image artifact" repo-token: ${{ secrets.GITHUB_TOKEN }} - name: Checkout - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: Install Nix - uses: DeterminateSystems/nix-installer-action@main + uses: DeterminateSystems/nix-installer-action@3138316df39ed29be04236d7ffc686fa525866aa # v23 - name: Build and save image artifact run: | @@ -76,7 +81,7 @@ jobs: ls -lh payjoin-mailroom-${TAG}.tar - name: Upload image artifact - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: payjoin-mailroom-image-${{ github.sha }} path: payjoin-mailroom-*.tar diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 07f9c1271..13c9215a7 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -2,6 +2,9 @@ name: Continuous integration on: [push, pull_request] +permissions: + contents: read + jobs: Test: runs-on: ubuntu-26.04 @@ -20,22 +23,25 @@ jobs: RUSTUP_TOOLCHAIN: ${{ matrix.rust }} steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install ${{ matrix.rust }} toolchain" - uses: dtolnay/rust-toolchain@master + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 with: # The toolchain must be specified manually, as this action ignores the rust-toolchain override # https://github.com/dtolnay/rust-toolchain?tab=readme-ov-file#inputs toolchain: ${{ matrix.rust }} - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Add nginxWithStream to PATH" run: | # This is necessary for payjoin-mailroom integration tests echo "$(nix build .#nginx-with-stream --print-out-paths --no-link)/bin" >> $GITHUB_PATH - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} shared-key: ${{ matrix.rust == 'stable' && 'stable-workspace' || matrix.rust == '1.85.0' && 'msrv-workspace' || '' }} - name: Run tests run: RUST_LOG=debug bash contrib/test.sh @@ -44,11 +50,15 @@ jobs: runs-on: ubuntu-26.04 steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Run code linting" run: nix develop -c ./contrib/lint.sh - name: "Run documentation linting" @@ -67,24 +77,32 @@ jobs: RUSTUP_TOOLCHAIN: stable steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install toolchain" # rust-cache usage with stable Rust is most effective, as a cache is tied to the Rust version - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: stable - name: Set up nix - uses: ./.github/actions/setup-nix + uses: $/.github/actions/setup-nix - name: "Add nginxWithStream to PATH" run: | # This is necessary for payjoin-mailroom integration tests echo "$(nix build .#nginx-with-stream --print-out-paths --no-link)/bin" >> $GITHUB_PATH - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: "Install cargo-llvm-cov" - uses: taiki-e/install-action@cargo-llvm-cov + uses: taiki-e/install-action@8cca0918f8471c33515202b73f56ab27f2bed283 # v2.87.29 + with: + tool: cargo-llvm-cov - name: "Generate code coverage for tests" run: bash contrib/coverage.sh - name: "Upload report to coveralls" - uses: coverallsapp/github-action@v2 + uses: coverallsapp/github-action@8d6379e14d29928660c4ba802d8e85393440b329 # v2.3.8 with: fail-on-error: false @@ -92,8 +110,10 @@ jobs: name: Code spell check runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 - - uses: codespell-project/actions-codespell@v2 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: codespell-project/actions-codespell@8f01853be192eb0f849a5c7d721450e7a467c579 # v2.2 DiffMutants: name: Diff cargo-mutants @@ -102,28 +122,37 @@ jobs: RUSTUP_TOOLCHAIN: stable steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 with: + persist-credentials: false # unneeded: no git auth beyond checkout fetch-depth: 0 # required for full diff context - name: Fetch base branch for diff - run: git fetch origin ${{ github.base_ref }} + env: + BASE_REF: ${{ github.base_ref }} + run: git fetch origin "$BASE_REF" - name: Relative diff + env: + BASE_REF: ${{ github.base_ref }} run: | git branch -av - git diff origin/${{ github.base_ref }}.. -- '*.rs' | tee git.diff - - uses: taiki-e/install-action@v2 + git diff origin/${BASE_REF}.. -- '*.rs' | tee git.diff + - uses: taiki-e/install-action@26e9283f268b880168bdbd2c545dfcd60ec2c6ab # v2.87.13 with: tool: cargo-mutants@27.1.0 - name: "Install toolchain" - uses: dtolnay/rust-toolchain@stable + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 + with: + toolchain: stable - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: Run cargo-mutants on diff run: > cargo mutants --no-shuffle --in-diff git.diff --test-tool=cargo --timeout=500 --build-timeout=500 - name: Upload mutants.out - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 if: always() with: name: mutants-incremental-cargo.out @@ -134,13 +163,17 @@ jobs: runs-on: ubuntu-26.04 steps: - name: "Checkout repo" - uses: actions/checkout@v6 + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout - name: "Install nightly toolchain" - uses: dtolnay/rust-toolchain@master + uses: dtolnay/rust-toolchain@683b588c487a69d01f6c6ddf40f036ff682cc2c8 # v1 with: # pinned nightly, bumped weekly by contrib/bump-nightly.sh toolchain: nightly-2026-10-12 - name: "Use cache" - uses: Swatinem/rust-cache@v2 + uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 + with: + lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} - name: "Build fuzz targets" run: cd fuzz && cargo build diff --git a/.github/workflows/standup-compile.yml b/.github/workflows/standup-compile.yml index 3241c780a..a20e02055 100644 --- a/.github/workflows/standup-compile.yml +++ b/.github/workflows/standup-compile.yml @@ -6,21 +6,27 @@ on: - cron: "0 6 * * 2" workflow_dispatch: +permissions: + contents: read + jobs: compile: runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.12" - run: pip install requests pyyaml - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-discussions: write - run: python .github/scripts/compile_standup.py env: GITHUB_REPOSITORY: ${{ github.repository }} diff --git a/.github/workflows/standup-on-comment.yml b/.github/workflows/standup-on-comment.yml index f8640ce69..639d9ee59 100644 --- a/.github/workflows/standup-on-comment.yml +++ b/.github/workflows/standup-on-comment.yml @@ -4,6 +4,9 @@ on: discussion_comment: types: [created] +permissions: + contents: read + jobs: respond: if: | @@ -14,17 +17,20 @@ jobs: contains(github.event.comment.body, '/check-in') runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.12" - run: pip install requests pyyaml - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-discussions: write - run: python .github/scripts/respond_to_standup_comment.py env: GITHUB_REPOSITORY: ${{ github.repository }} diff --git a/.github/workflows/standup-prompt.yml b/.github/workflows/standup-prompt.yml index aa3cfaa30..e2d34c375 100644 --- a/.github/workflows/standup-prompt.yml +++ b/.github/workflows/standup-prompt.yml @@ -11,21 +11,27 @@ on: required: false default: "" +permissions: + contents: read + jobs: create-discussion: runs-on: ubuntu-26.04 steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v5 + - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false # unneeded: no git auth beyond checkout + - uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065 # v5.6.0 with: python-version: "3.12" - run: pip install requests pyyaml - name: Mint bot token id: bot-token - uses: actions/create-github-app-token@v2 + uses: actions/create-github-app-token@fee1f7d63c2ff003460e3d139729b119787bc349 # v2.2.2 with: app-id: ${{ vars.BOT_APP_ID }} private-key: ${{ secrets.BOT_APP_PRIVATE_KEY }} + permission-discussions: write - run: python .github/scripts/create_standup_discussion.py env: GITHUB_REPOSITORY: ${{ github.repository }} diff --git a/payjoin-ffi/javascript/smoke/.gitignore b/payjoin-ffi/javascript/smoke/.gitignore new file mode 100644 index 000000000..b6511d56c --- /dev/null +++ b/payjoin-ffi/javascript/smoke/.gitignore @@ -0,0 +1,2 @@ +pkg/ +node_modules/ diff --git a/payjoin-ffi/javascript/smoke/package-lock.json b/payjoin-ffi/javascript/smoke/package-lock.json new file mode 100644 index 000000000..368dc03c0 --- /dev/null +++ b/payjoin-ffi/javascript/smoke/package-lock.json @@ -0,0 +1,38 @@ +{ + "name": "payjoin-smoke", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "payjoin-smoke", + "version": "0.0.0", + "dependencies": { + "payjoin": "file:./pkg/payjoin.tgz" + } + }, + "node_modules/@ubjs/core": { + "version": "0.31.0-6", + "resolved": "https://registry.npmjs.org/@ubjs/core/-/core-0.31.0-6.tgz", + "integrity": "sha512-pscv6Zj8mVmd5+ikb1Zr6XZ0yqYwKGeIV8HU8rf9sTvs7GW34OARAp03xFJ7rE9XE4R6LgwQhzYW9knAuz5yxA==", + "license": "MPL-2.0" + }, + "node_modules/payjoin": { + "version": "0.3.0", + "resolved": "file:pkg/payjoin.tgz", + "dependencies": { + "@ubjs/core": "^0.31.0-3", + "uniffi-bindgen-react-native": "github:spacebear21/uniffi-bindgen-react-native#d10f04d83299" + } + }, + "node_modules/uniffi-bindgen-react-native": { + "version": "0.31.0-3", + "resolved": "git+ssh://git@github.com/spacebear21/uniffi-bindgen-react-native.git#d10f04d83299688d1ed7427841e2c8348a64e4a3", + "license": "MPL-2.0", + "bin": { + "ubrn": "bin/cli.cjs", + "uniffi-bindgen-react-native": "bin/cli.cjs" + } + } + } +} diff --git a/payjoin-ffi/javascript/smoke/package.json b/payjoin-ffi/javascript/smoke/package.json new file mode 100644 index 000000000..3a4c37820 --- /dev/null +++ b/payjoin-ffi/javascript/smoke/package.json @@ -0,0 +1,9 @@ +{ + "name": "payjoin-smoke", + "version": "0.0.0", + "private": true, + "description": "Installs the packed npm tarball through a committed lockfile so the smoke test never installs anything ad-hoc.", + "dependencies": { + "payjoin": "file:./pkg/payjoin.tgz" + } +} From 79764ec224154360b4ccb92f8cf36ed0fe5ea6a6 Mon Sep 17 00:00:00 2001 From: Benalleng Date: Fri, 16 Oct 2026 12:08:53 -0400 Subject: [PATCH 2/4] lock lockfile for fuzz build CI job --- .github/workflows/rust.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 13c9215a7..157cbb017 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -175,5 +175,7 @@ jobs: uses: Swatinem/rust-cache@6323deb102c322ba6fcbdcafc7e3dddab59af2b6 # v2.9.2 with: lookup-only: ${{ startsWith(github.ref, 'refs/tags/') }} + - name: "Prepare lockfile" + run: cp Cargo-recent.lock Cargo.lock - name: "Build fuzz targets" - run: cd fuzz && cargo build + run: cd fuzz && cargo build --locked From e6dde22906bf139966ca7ed8e7c2799c3b38165e Mon Sep 17 00:00:00 2001 From: Benalleng Date: Wed, 16 Sep 2026 13:45:46 -0400 Subject: [PATCH 3/4] Introduce zizmor CI checks --- .github/workflows/zizmor.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/zizmor.yml diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml new file mode 100644 index 000000000..d65050224 --- /dev/null +++ b/.github/workflows/zizmor.yml @@ -0,0 +1,27 @@ +name: GitHub Actions Security Analysis with zizmor 🌈 + +on: + pull_request: + branches: ["**"] + paths: + - ".github/**" + +permissions: {} + +jobs: + zizmor: + name: zizmor via PyPI + runs-on: ubuntu-26.04 + steps: + - name: Checkout repository + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@11f9893b081a58869d3b5fccaea48c9e9e46f990 # v8.3.2 + + - name: Run zizmor 🌈 + run: uvx zizmor@1.30.1 . + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} From a5476173f249da5740596ce3b0c5c4b3b68bb7cb Mon Sep 17 00:00:00 2001 From: Benalleng Date: Mon, 12 Oct 2026 12:37:47 -0400 Subject: [PATCH 4/4] Add dependabot configuration for updating non-semver refs Following the zizmor hash pinning we need a dependabot job to update our workflow action checks to keep things current. --- .github/dependabot.yml | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000..52b4edc36 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,26 @@ +version: 2 +updates: + - package-ecosystem: uv + cooldown: + default-days: 7 + directory: "/payjoin-ffi/python" + schedule: + interval: weekly + groups: + uv: + patterns: + - "*" + + - package-ecosystem: github-actions + # All action pins use tag comments so Dependabot can update them. Toolchain + # channels (stable/nightly/MSRV) are passed via the toolchain input instead + # of branch refs, which Dependabot cannot track. + cooldown: + default-days: 7 + directories: ["/", "/.github/actions/*"] + schedule: + interval: weekly + groups: + github-actions: + patterns: + - "*"