<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <updated></updated>
  <generator>https://nostr.ae</generator>

  <title>Nostr notes by </title>
  <author>
    <name></name>
  </author>
  <link rel="self" type="application/atom+xml" href="https://nostr.ae/npub1g8jqaty8lf8qzsvtsxvayrhz94w308rlmxqfkel6f4d4d7cpkyaq2z3zcu.rss" />
  <link href="https://nostr.ae/npub1g8jqaty8lf8qzsvtsxvayrhz94w308rlmxqfkel6f4d4d7cpkyaq2z3zcu" />
  <id>https://nostr.ae/npub1g8jqaty8lf8qzsvtsxvayrhz94w308rlmxqfkel6f4d4d7cpkyaq2z3zcu</id>
  <icon></icon>
  <logo></logo>




  <entry>
    <id>https://nostr.ae/nevent1qqswpcf2zmnhxsf8584fjnvj2srymeqenh2jsqz0pxlnv2920vzn78qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5y6dytd</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswpcf2zmnhxsf8584fjnvj2srymeqenh2jsqz0pxlnv2920vzn78qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5y6dytd" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:10:13&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsyldumc9gnvl036rqjztcu8j8f7cnusara3qfs47ruzhe8q4fl7zgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5463sv8</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsyldumc9gnvl036rqjztcu8j8f7cnusara3qfs47ruzhe8q4fl7zgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5463sv8" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:09:52&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs003q8lqcm0hjxmwq0rg23hedldfxzr37ee2seu4d46ksyfmd2jxszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5y03elv</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs003q8lqcm0hjxmwq0rg23hedldfxzr37ee2seu4d46ksyfmd2jxszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5y03elv" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:09:33&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsw24pc8r7fdnzxd6xvxy23u8xhesqfc9dwkz0nlj0tn3j6h44d9wqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5956zsp</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsw24pc8r7fdnzxd6xvxy23u8xhesqfc9dwkz0nlj0tn3j6h44d9wqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5956zsp" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:09:10&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqszuuedp7gnp8ftd9wy28wtdlw2np5zwadz30f9zp0lfzzt5g8syhczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52m2nug</id>
    
      <title>Nostr event nevent1qqszuuedp7gnp8ftd9wy28wtdlw2np5zwadz30f9zp0lfzzt5g8syhczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52m2nug</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqszuuedp7gnp8ftd9wy28wtdlw2np5zwadz30f9zp0lfzzt5g8syhczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52m2nug" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:08:45&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsx3xrs6h9qqzd4jtkxndzmgp86m6vulff8uzllvy0sekd0v9sjc3szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53322fx</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsx3xrs6h9qqzd4jtkxndzmgp86m6vulff8uzllvy0sekd0v9sjc3szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53322fx" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:08:25&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqszef9cnjmr8ylvzc7pnqa7wfhzdc58u8fvuwwjuyqp6a3lg77gspqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5swch7r</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqszef9cnjmr8ylvzc7pnqa7wfhzdc58u8fvuwwjuyqp6a3lg77gspqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5swch7r" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:08:05&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsylwgr89tk0m58c9mlvgv0he3gqs26zhmny4hfrxs3ttk507ghw7qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn59n9rj8</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsylwgr89tk0m58c9mlvgv0he3gqs26zhmny4hfrxs3ttk507ghw7qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn59n9rj8" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:07:15&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdyh9tn4lmvky2xt9lrwjxwct24fuqwqrc9tcjrqkmgsqetg9h2rczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vxepv5</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdyh9tn4lmvky2xt9lrwjxwct24fuqwqrc9tcjrqkmgsqetg9h2rczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vxepv5" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:06:55&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsfqus3a6jqs44va8zyv86nac57saue9e368p38m7rfughxhxp49fgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fsh8uj</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsfqus3a6jqs44va8zyv86nac57saue9e368p38m7rfughxhxp49fgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fsh8uj" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:06:11&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdnut8g83vvhpfht88vpdxp07datx4cmvnqfmvx5tw48vw4trk5jszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5tnzp4e</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdnut8g83vvhpfht88vpdxp07datx4cmvnqfmvx5tw48vw4trk5jszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5tnzp4e" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:05:05&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs07zhetl3um7vgk4390echkj2ckjhmwcha4crql4pffhyd9r0zzeqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5hrwf0u</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs07zhetl3um7vgk4390echkj2ckjhmwcha4crql4pffhyd9r0zzeqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5hrwf0u" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:04:44&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs20nn6ghsahr9fwu5xqqxupqxva9vhlmfzfryjuh4azseas7rm3yqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a22mat</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs20nn6ghsahr9fwu5xqqxupqxva9vhlmfzfryjuh4azseas7rm3yqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a22mat" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:03:30&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdvqagq6zq5hcr7eq08r5rz6qavmvp8y64c4u8hxj956kf62wfkkqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5nlxexu</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdvqagq6zq5hcr7eq08r5rz6qavmvp8y64c4u8hxj956kf62wfkkqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5nlxexu" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:02:46&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsw5kt0uxfs493gyulrervkpesjr30ysq0wdw02haekckzgrsvpsxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5sfaz78</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsw5kt0uxfs493gyulrervkpesjr30ysq0wdw02haekckzgrsvpsxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5sfaz78" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T18:02:26&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsxygghyz4sffgegjx34654m58e35qus0hkthdhtwetfc4uuws5u0szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn590fsh3</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsxygghyz4sffgegjx34654m58e35qus0hkthdhtwetfc4uuws5u0szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn590fsh3" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:57:01&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsfjkjnymte0eahwyfedceltqxkj035mge9tr0x3knsce5fu0ekn2gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52439nz</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsfjkjnymte0eahwyfedceltqxkj035mge9tr0x3knsce5fu0ekn2gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52439nz" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:56:35&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdexu9ys0txp55sp57y43rsjxl9xsnykzetrt7253n3qc3glczpkczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5wdh2ts</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdexu9ys0txp55sp57y43rsjxl9xsnykzetrt7253n3qc3glczpkczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5wdh2ts" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:56:19&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsqdzpvu7ggqftul9raagfnx77naayl4g7s5pgse9qmpde5ewmrsygzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jxsyy0</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsqdzpvu7ggqftul9raagfnx77naayl4g7s5pgse9qmpde5ewmrsygzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jxsyy0" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:56:04&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0rhxqvsw8a0lj98vjhp3euc5wdum3yq54ldcsdqsw3086vdfswgszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54myv7j</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0rhxqvsw8a0lj98vjhp3euc5wdum3yq54ldcsdqsw3086vdfswgszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54myv7j" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:55:58&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs22ter0ck4hdd2j6r3t3zmmswn5aax745848gxsllu7uhzrsrxx0qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5yenwn0</id>
    
      <title>Nostr event nevent1qqs22ter0ck4hdd2j6r3t3zmmswn5aax745848gxsllu7uhzrsrxx0qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5yenwn0</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs22ter0ck4hdd2j6r3t3zmmswn5aax745848gxsllu7uhzrsrxx0qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5yenwn0" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:53:29&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsp69jm8xvy8lsvu45f86ajxs7h96xaq0lskg257mfknqu9dgkvjhqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57u3yf9</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsp69jm8xvy8lsvu45f86ajxs7h96xaq0lskg257mfknqu9dgkvjhqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57u3yf9" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:53:11&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsth7jsqm36ht42czs6qzwvdnqdypl5dum00u76vw7x8zd2v53wedczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52hhs7n</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsth7jsqm36ht42czs6qzwvdnqdypl5dum00u76vw7x8zd2v53wedczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52hhs7n" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:52:50&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsw20l5fxt8mkp0szpaspz9thqqmreztfaf3095l64jl9fsjrq3p3gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5kd5426</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsw20l5fxt8mkp0szpaspz9thqqmreztfaf3095l64jl9fsjrq3p3gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5kd5426" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:52:21&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsxzj97d6yuxwv42npv89cgn69e5wteqwqgsrmw0y2kkklm9jcgakczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5dmscdq</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsxzj97d6yuxwv42npv89cgn69e5wteqwqgsrmw0y2kkklm9jcgakczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5dmscdq" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:52:01&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsycn68355w7sx0u26cdn6ksk4e3jtaef7na8ad6h5glrfzw5utq8czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fw72yj</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsycn68355w7sx0u26cdn6ksk4e3jtaef7na8ad6h5glrfzw5utq8czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fw72yj" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:51:47&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0xd9s8ucynth5t8cqhyl6dx55d3xr8d3umsghd8quctzc898frqqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5lyjta8</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0xd9s8ucynth5t8cqhyl6dx55d3xr8d3umsghd8quctzc898frqqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5lyjta8" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:51:33&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0r4u05zj39yg0jccd58s0zgkg6hsk0wmnngmfxe9kg6cf9zk7h6czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5urxjjd</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0r4u05zj39yg0jccd58s0zgkg6hsk0wmnngmfxe9kg6cf9zk7h6czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5urxjjd" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:51:21&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0y5dh5gk0c3nc6zn2unwhy7pyz27dgse2zkv3h9ukxn07e9lz72czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jes0m3</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0y5dh5gk0c3nc6zn2unwhy7pyz27dgse2zkv3h9ukxn07e9lz72czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jes0m3" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:50:55&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqst7ddksfcxa8y2utnt9mrft4t8yugxj20ftxx5a3k2vw4fj7dvs9gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qtnl2d</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqst7ddksfcxa8y2utnt9mrft4t8yugxj20ftxx5a3k2vw4fj7dvs9gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qtnl2d" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:50:00&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsx85ard7n68fwmaswrea59ytpsc3jlqxxwx5v6xzpmq79w0sh7nugzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ljz4gm</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsx85ard7n68fwmaswrea59ytpsc3jlqxxwx5v6xzpmq79w0sh7nugzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ljz4gm" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:49:34&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsycxyzemrl37kpvnnhqm5t9cwu8wdt8w6f9f6dkrqpl7mtxhydexgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5pc70uz</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsycxyzemrl37kpvnnhqm5t9cwu8wdt8w6f9f6dkrqpl7mtxhydexgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5pc70uz" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:48:43&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsvxa8s5362z90pccq8j9c6h522undjelkz59la2d9095fwynnxkdczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5eqm4cj</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsvxa8s5362z90pccq8j9c6h522undjelkz59la2d9095fwynnxkdczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5eqm4cj" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:48:15&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqstt0z9lsx4zthdkl5m7uxw2avylvw8mqzhtep4783s59jc3pvzh8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57j7gc6</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqstt0z9lsx4zthdkl5m7uxw2avylvw8mqzhtep4783s59jc3pvzh8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57j7gc6" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:48:11&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqszulkxqura5sj6q6js0zfl2p4w97n23fs5y030gjrycedm078fdvczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5g73m45</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqszulkxqura5sj6q6js0zfl2p4w97n23fs5y030gjrycedm078fdvczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5g73m45" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:47:50&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs930ve46w8mhexf8gz5ygylp70y4pdwn725v4ldf6llr5kp8dd8jszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53y27q3</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs930ve46w8mhexf8gz5ygylp70y4pdwn725v4ldf6llr5kp8dd8jszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53y27q3" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:46:51&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsqmrqs5eceyyexejrx3r8f2cu4rrzym8vrj78p8csuct4d6vxwtmgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5wvv2pn</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsqmrqs5eceyyexejrx3r8f2cu4rrzym8vrj78p8csuct4d6vxwtmgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5wvv2pn" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:46:31&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0j3kjmhf9pvngu8ydlqxy3gf8t66v8d3a34rel7s9j08csjntxxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5tdqlew</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0j3kjmhf9pvngu8ydlqxy3gf8t66v8d3a34rel7s9j08csjntxxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5tdqlew" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:46:01&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdylgyymmkpkwtfmpqh7hzdv3848su8c7jexlcpruv3u7wyd8d2kszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vau4st</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdylgyymmkpkwtfmpqh7hzdv3848su8c7jexlcpruv3u7wyd8d2kszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vau4st" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:45:41&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqspvjeq60j74zye62fvkutn0yaztl8a8n5f5rev2cdpd9w2kywmn4gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ej8c4e</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqspvjeq60j74zye62fvkutn0yaztl8a8n5f5rev2cdpd9w2kywmn4gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ej8c4e" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:42:50&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsyc887mwwg36z28rtdg9v6q50tcncf3nvtewvez3c0dclxqmlt2mczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5dmcsh4</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsyc887mwwg36z28rtdg9v6q50tcncf3nvtewvez3c0dclxqmlt2mczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5dmcsh4" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:39:49&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsr2c70agzk40pk8u5gzr7r9a9tz23xj4sx68ah4l7s080f8fung8gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qjs8zc</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsr2c70agzk40pk8u5gzr7r9a9tz23xj4sx68ah4l7s080f8fung8gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qjs8zc" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:39:34&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs8qqzhjngct5tr53dz85r2rz8ph4vd6crgu8793vgf5j0exth86qgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5c6u5le</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs8qqzhjngct5tr53dz85r2rz8ph4vd6crgu8793vgf5j0exth86qgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5c6u5le" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_issue;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let issue_id = &amp;#34;123&amp;#34;;&lt;br/&gt;    let title = &amp;#34;Bug: Fix authentication flow example&amp;#34;;&lt;br/&gt;    let content = &amp;#34;The authentication flow is currently broken when users try to log in with invalid credentials. It crashes instead of showing an error message.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id,&lt;br/&gt;        title,&lt;br/&gt;        content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id,&lt;br/&gt;        title,&lt;br/&gt;        content,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_issue --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:39:16&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsgkr3vdrqq99t4ray3zehzp8nuj849dng2yej9hamaesn95kfakaszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a928ud</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsgkr3vdrqq99t4ray3zehzp8nuj849dng2yej9hamaesn95kfakaszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a928ud" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_post_signer()&lt;br/&gt;}&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox_post --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:39:00&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs9yd5qv33p8rm2f0dwnf0v94690qpvcglx8fhxkeaxuxfknpzwlaqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ewm9dl</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs9yd5qv33p8rm2f0dwnf0v94690qpvcglx8fhxkeaxuxfknpzwlaqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ewm9dl" />
    <content type="html">
      &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_coordinator()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:38:44&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqstxmc7f8uu2y52dqn4wqe2tegf4js3rmteu2qd27g8hycsrrya0ugzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5glnr87</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqstxmc7f8uu2y52dqn4wqe2tegf4js3rmteu2qd27g8hycsrrya0ugzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5glnr87" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; // MUST use the -tr variant for BIP-340/Nostr&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use serde_json::json;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (3, 2);&lt;br/&gt;&lt;br/&gt;    // 1. Setup Nostr Event Metadata&lt;br/&gt;    let pubkey_hex = &amp;#34;79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798&amp;#34;; // Example&lt;br/&gt;    let created_at = 1712050000;&lt;br/&gt;    let kind = 1;&lt;br/&gt;    let content = &amp;#34;Hello from ROAST threshold signatures!&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // 2. Serialize for Nostr ID (per NIP-01)&lt;br/&gt;    let event_json = json!([&lt;br/&gt;        0,&lt;br/&gt;        pubkey_hex,&lt;br/&gt;        created_at,&lt;br/&gt;        kind,&lt;br/&gt;        [],&lt;br/&gt;        content&lt;br/&gt;    ]).to_string();&lt;br/&gt;    &lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(event_json.as_bytes());&lt;br/&gt;    let event_id = hasher.finalize(); // This 32-byte hash is our signing message&lt;br/&gt;&lt;br/&gt;    // 3. FROST/ROAST Key Generation&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 4. ROAST Coordination Simulation (Round 1: Commitments)&lt;br/&gt;    // In ROAST, the coordinator keeps a &amp;#34;session&amp;#34; open and collects commitments&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    let mut signer_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Signers 1 and 3 respond first (Signer 2 is offline/slow)&lt;br/&gt;    for &amp;amp;id_val in &amp;amp;[1, 3] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_val as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        session_commitments.insert(id, comms);&lt;br/&gt;        signer_nonces.insert(id, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 5. Round 2: Signing the Nostr ID&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, &amp;amp;event_id);&lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    for (id, nonces) in signer_nonces {&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(id, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 6. Aggregate into a BIP-340 Signature&lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 7. Verification (using BIP-340 logic)&lt;br/&gt;    pubkey_package.verifying_key().verify(&amp;amp;event_id, &amp;amp;group_signature)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Nostr Event ID: {}&amp;#34;, hex::encode(event_id));&lt;br/&gt;    println!(&amp;#34;Threshold Signature (BIP-340): {}&amp;#34;, hex::encode(group_signature.serialize()?));&lt;br/&gt;    println!(&amp;#34;Successfully signed Nostr event using ROAST/FROST!&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_bip_340 --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:38:25&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsg0h86kc6gtl9t277dmts5gqc4a3fq7ckn0n5yg4x2m7ueuqrlm0gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn59dralj</id>
    
      <title type="html"># dist plan --output-format=json &amp;gt; plan-dist-manifest.json # ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsg0h86kc6gtl9t277dmts5gqc4a3fq7ckn0n5yg4x2m7ueuqrlm0gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn59dralj" />
    <content type="html">
      # dist plan --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[workspace]&lt;br/&gt;members = [&amp;#34;cargo:.&amp;#34;, &amp;#34;cargo:src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[dist]&lt;br/&gt;# The preferred dist version to use in CI (Cargo.toml SemVer syntax)&lt;br/&gt;cargo-dist-version = &amp;#34;0.30.3&amp;#34;&lt;br/&gt;# CI backends to support&lt;br/&gt;ci = &amp;#34;github&amp;#34;&lt;br/&gt;# The installers to generate for each app&lt;br/&gt;installers = [&amp;#34;shell&amp;#34;, &amp;#34;powershell&amp;#34;, &amp;#34;homebrew&amp;#34;, &amp;#34;msi&amp;#34;]&lt;br/&gt;# A GitHub repo to push Homebrew formulas to&lt;br/&gt;tap = &amp;#34;gnostr-org/homebrew-gnostr-org&amp;#34;&lt;br/&gt;# Path that installers should place binaries in&lt;br/&gt;install-path = &amp;#34;CARGO_HOME&amp;#34;&lt;br/&gt;# Publish jobs to run in CI&lt;br/&gt;publish-jobs = [&amp;#34;homebrew&amp;#34;]&lt;br/&gt;# Whether to install an updater program&lt;br/&gt;install-updater = true&lt;br/&gt;# Target platforms to build apps for (Rust target-triple syntax)&lt;br/&gt;targets = [&amp;#34;aarch64-apple-darwin&amp;#34;, &amp;#34;aarch64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-apple-darwin&amp;#34;, &amp;#34;x86_64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-unknown-linux-musl&amp;#34;, &amp;#34;x86_64-pc-windows-msvc&amp;#34;]&lt;br/&gt;# Skip checking whether the specified configuration files are up to date&lt;br/&gt;allow-dirty = [&amp;#34;ci&amp;#34;]&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:38:08&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsv8zk9jz8q6yc005enc5e60csu8mq70hh64njjgz9veemkw9wh0fczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5gy7k4j</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsv8zk9jz8q6yc005enc5e60csu8mq70hh64njjgz9veemkw9wh0fczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5gy7k4j" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, EventId, Tag, SecretKey, JsonUtil, Kind, Event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use serde_json::to_string;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::io::Write;&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn should_remove_relay(error_msg: &amp;amp;str) -&amp;gt; bool {&lt;br/&gt;    error_msg.contains(&amp;#34;relay not connected&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;not in web of trust&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;blocked: not authorized&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;timeout&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;blocked: spam not permitted&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;relay experienced an error trying to publish the latest event&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;duplicate: event already broadcast&amp;#34;)&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn write_event_json_to_file(&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    filename: &amp;amp;str,&lt;br/&gt;    event: &amp;amp;Event,&lt;br/&gt;) -&amp;gt; Option&amp;lt;()&amp;gt; {&lt;br/&gt;    let file_path = output_dir.join(filename);&lt;br/&gt;    if let Some(parent) = file_path.parent() {&lt;br/&gt;        if let Err(e) = fs::create_dir_all(parent) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create parent directories for {}: {}&amp;#34;, file_path.display(), e);&lt;br/&gt;            return None;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    if let Err(e) = fs::File::create(&amp;amp;file_path).and_then(|mut file| write!(file, &amp;#34;{}&amp;#34;, event.as_json())) {&lt;br/&gt;        println!(&amp;#34;Failed to write event JSON to file {}: {}&amp;#34;, file_path.display(), e);&lt;br/&gt;        None&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;Successfully wrote event JSON to {}&amp;#34;, file_path.display());&lt;br/&gt;        Some(())&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;async fn publish_nostr_event_if_release(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    hash: String,&lt;br/&gt;    keys: Keys,&lt;br/&gt;    event_builder: EventBuilder,&lt;br/&gt;    _relay_urls: &amp;amp;mut Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    file_path_str: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    total_bytes_sent: &amp;amp;mut usize,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;    let public_key = keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr event for {}: {}&amp;#34;, file_path_str, event_output.val);&lt;br/&gt;&lt;br/&gt;            let event_json_size = to_string(&amp;amp;event).map(|s| s.as_bytes().len()).unwrap_or(0);&lt;br/&gt;            // Print successful relays&lt;br/&gt;            for relay_url in event_output.success.iter() {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Successfully published to relay: {} ({} bytes)&amp;#34;, relay_url, event_json_size);&lt;br/&gt;                *total_bytes_sent &#43;= event_json_size;&lt;br/&gt;            }&lt;br/&gt;            // Print failed relays and remove &amp;#34;unfriendly&amp;#34; relays from the list&lt;br/&gt;            for (relay_url, error_msg) in event_output.failed.iter() {&lt;br/&gt;                if should_remove_relay(error_msg) {&lt;br/&gt;                    if let Err(e) = client.remove_relay(relay_url).await {&lt;br/&gt;                        println!(&amp;#34;cargo:warning=Failed to remove relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;                    }&lt;br/&gt;                     // println!(&amp;#34;cargo:warning=Removed relay {}&amp;#34;, relay_url);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let filename = format!(&amp;#34;{}/{}/{}/{}.json&amp;#34;, file_path_str, hash, public_key.clone(), event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr event for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;pub async fn get_repo_announcement_event(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    _keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    repo_url: &amp;amp;str,&lt;br/&gt;    repo_name: &amp;amp;str,&lt;br/&gt;    repo_description: &amp;amp;str,&lt;br/&gt;    git_commit_hash: &amp;amp;str,&lt;br/&gt;    git_branch: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    public_key_hex: &amp;amp;str,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::parse([&amp;#34;d&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;description&amp;#34;, repo_description].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;web&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;clone&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;r&amp;#34;, git_commit_hash, &amp;#34;euc&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, git_commit_hash].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;branch&amp;#34;, git_branch].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;maintainers&amp;#34;, &amp;#34;gnostr&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        //Tag::parse([&amp;#34;t&amp;#34;, &amp;#34;personal-fork&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;t&amp;#34;, &amp;#34;gnostr&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;t&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    // Append each relay url&lt;br/&gt;    for relay in relay_urls {&lt;br/&gt;        tags.push(Tag::parse([&amp;#34;relays&amp;#34;, relay].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap());&lt;br/&gt;    }&lt;br/&gt;    let event_builder = EventBuilder::new(Kind::Custom(30617), repo_description).tags(tags);&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {&lt;br/&gt;        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, event_output.val);&lt;br/&gt;            &lt;br/&gt;            let filename = format!(&amp;#34;30617/{}/{}/{}.json&amp;#34;, repo_name, public_key_hex, event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;pub async fn get_repo_patch_event(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    _keys: &amp;amp;Keys,&lt;br/&gt;    _relay_urls: &amp;amp;Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    repo_url: &amp;amp;str,&lt;br/&gt;    repo_name: &amp;amp;str,&lt;br/&gt;    repo_description: &amp;amp;str,&lt;br/&gt;    git_commit_hash: &amp;amp;str,&lt;br/&gt;    git_branch: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    public_key_hex: &amp;amp;str,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;&lt;br/&gt;    let tags = vec![&lt;br/&gt;        Tag::parse([&amp;#34;r&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;description&amp;#34;, repo_description].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, git_commit_hash].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;branch&amp;#34;, git_branch].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(Kind::Custom(1617), repo_description).tags(tags);&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {&lt;br/&gt;        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, event_output.val);&lt;br/&gt;            &lt;br/&gt;            let filename = format!(&amp;#34;30617/{}/{}/{}.json&amp;#34;, repo_name, public_key_hex, event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;    let mut git_commit_hash_str = String::new();&lt;br/&gt;    let mut git_branch_str = String::new();&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_keys = Keys::new(SecretKey::from_hex(&amp;amp;hex::encode(Sha256::digest(&amp;#34;initial_seed&amp;#34;.as_bytes()))).expect(&amp;#34;Failed to create initial Nostr keys&amp;#34;));&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;&lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = &amp;amp;git_commit_hash_str;&lt;br/&gt;            let git_branch = &amp;amp;git_branch_str;&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes ({} MB)&amp;#34;, total_bytes_sent, total_bytes_sent as f64 / 1024.0 / 1024.0);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:37:47&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsrw6rmk27k2nwg3f0gdlmtzmymtspgj8s4y7kv9af6y4v0x6mte0czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vzv6s6</id>
    
      <title type="html"># `get_file_hash` macro This project provides a Rust procedural ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsrw6rmk27k2nwg3f0gdlmtzmymtspgj8s4y7kv9af6y4v0x6mte0czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5vzv6s6" />
    <content type="html">
      # `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;*   **SHA-256 Hash:** 6c6325c5a4c14f44cbda6ca53179ab3d6666ce7c916365668c6dd1d79215db59&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;*   **SHA-256 Hash:** 20c958c8cbb5c77cf5eb3763b6da149b61241d328df52d39b7aa97903305c889&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;*   **SHA-256 Hash:** e3f392bf23b5fb40902acd313a8c76d1943060b6805ea8615de62f9baf0c6513&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;*   **SHA-256 Hash:** 591593482a6c9aac8793aa1e488e613f52a4effb1ec3465fd9d6a54537f2b123&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:37:32&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqswsuefdx6v8k2yerpx27cxmxxslmawg9qs645yjh680x5usm5fuhqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5r5smcd</id>
    
      <title type="html">[workspace] members = [&amp;#34;.&amp;#34;, ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswsuefdx6v8k2yerpx27cxmxxslmawg9qs645yjh680x5usm5fuhqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5r5smcd" />
    <content type="html">
      [workspace]&lt;br/&gt;members = [&amp;#34;.&amp;#34;, &amp;#34;src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.package]&lt;br/&gt;version = &amp;#34;0.3.3&amp;#34;&lt;br/&gt;edition = &amp;#34;2024&amp;#34;&lt;br/&gt;license = &amp;#34;MIT&amp;#34;&lt;br/&gt;authors = [&amp;#34;gnostr admin@gnostr.org&amp;#34;]&lt;br/&gt;documentation = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&lt;/a&gt;;&lt;br/&gt;homepage = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;repository = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;description = &amp;#34;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#34;&lt;br/&gt;&lt;br/&gt;[package]&lt;br/&gt;name = &amp;#34;get_file_hash&amp;#34;&lt;br/&gt;version.workspace = true&lt;br/&gt;edition.workspace = true&lt;br/&gt;description.workspace = true&lt;br/&gt;repository.workspace = true&lt;br/&gt;homepage.workspace = true&lt;br/&gt;authors.workspace = true&lt;br/&gt;license.workspace = true&lt;br/&gt;&lt;br/&gt;[package.metadata.wix]&lt;br/&gt;upgrade-guid = &amp;#34;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#34;&lt;br/&gt;path-guid = &amp;#34;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#34;&lt;br/&gt;license = false&lt;br/&gt;eula = false&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:hex&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.dependencies]&lt;br/&gt;get_file_hash_core = { features = [&amp;#34;nostr&amp;#34;], path = &amp;#34;src/get_file_hash_core&amp;#34;, version = &amp;#34;0.3.3&amp;#34; }&lt;br/&gt;sha2 = &amp;#34;0.11.0&amp;#34;&lt;br/&gt;nostr = &amp;#34;0.44.2&amp;#34;&lt;br/&gt;nostr-sdk = &amp;#34;0.44.0&amp;#34;&lt;br/&gt;hex = &amp;#34;0.4.2&amp;#34;&lt;br/&gt;tokio = &amp;#34;1&amp;#34;&lt;br/&gt;serde_json = &amp;#34;1.0&amp;#34;&lt;br/&gt;csv = { version = &amp;#34;1.3.0&amp;#34;, default-features = false }&lt;br/&gt;url = &amp;#34;2.5.0&amp;#34;&lt;br/&gt;reqwest = { version = &amp;#34;0.12.0&amp;#34;, default-features = false }&lt;br/&gt;tempfile = &amp;#34;3.27.0&amp;#34;&lt;br/&gt;rand = &amp;#34;0.8&amp;#34;&lt;br/&gt;frost-secp256k1-tr = &amp;#34;3.0.0-rc.0&amp;#34;&lt;br/&gt;serial_test = { version = &amp;#34;3.4.0&amp;#34;, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = &amp;#34;0.4&amp;#34;&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;]  }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;rand = { workspace = true }&lt;br/&gt;serde_json.workspace = true&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;] }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;&lt;br/&gt;# The profile that &amp;#39;dist&amp;#39; will build with&lt;br/&gt;[profile.dist]&lt;br/&gt;inherits = &amp;#34;release&amp;#34;&lt;br/&gt;lto = &amp;#34;thin&amp;#34;&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;serial_test = { workspace = true }&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:37:15&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs2egec4zpcdypjuehn96jtzd237c2qdr0sx7a4fx59x4upeejj2fgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5axln82</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs2egec4zpcdypjuehn96jtzd237c2qdr0sx7a4fx59x4upeejj2fgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5axln82" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:36:59&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsv9tl3wflmat5py495v2kpwat4pts65ge5ndjsed6cjxgv3jhrtpczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5n3hlr5</id>
    
      <title>Nostr event nevent1qqsv9tl3wflmat5py495v2kpwat4pts65ge5ndjsed6cjxgv3jhrtpczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5n3hlr5</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsv9tl3wflmat5py495v2kpwat4pts65ge5ndjsed6cjxgv3jhrtpczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5n3hlr5" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:36:43&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs948ujp4us0q0vs93rjvchtgcclw4697apgvz6wmrdf8r6vq03yhszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a2anr0</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs948ujp4us0q0vs93rjvchtgcclw4697apgvz6wmrdf8r6vq03yhszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5a2anr0" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:36:26&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsrt3yda7tjr4c966q0ghq804cn77hurrsxh693d2cn2jep0dtzsxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jhr5xn</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsrt3yda7tjr4c966q0ghq804cn77hurrsxh693d2cn2jep0dtzsxczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jhr5xn" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:36:05&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdmgguah0ez34sv6y0efterjzatl8cv3x2vufx408q32k9f69c3sqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ksyjde</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdmgguah0ez34sv6y0efterjzatl8cv3x2vufx408q32k9f69c3sqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ksyjde" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:27:38&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqszsy675h5dcgv3dqftpr0s4z0h48m23f8t42p0tzwntjtt6h9nw8szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5t6zjwx</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqszsy675h5dcgv3dqftpr0s4z0h48m23f8t42p0tzwntjtt6h9nw8szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5t6zjwx" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:27:25&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs2xctfwesmxhz0q64u9swqeyf20ux60kw7zde7v23k3cxte626gkszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5whm3ca</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs2xctfwesmxhz0q64u9swqeyf20ux60kw7zde7v23k3cxte626gkszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5whm3ca" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:27:12&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsy8ewq899w4lch69ea3amcaur7l82xh8h5daqmrr4r4ks64vhsspqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn56q7smt</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsy8ewq899w4lch69ea3amcaur7l82xh8h5daqmrr4r4ks64vhsspqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn56q7smt" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:23:05&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsdwdem2kwl8jsw0zazlpxkulkl25mxscz4vulq34vwchu49af4tpczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5egwjp3</id>
    
      <title type="html">Build manifest for get_file_hash v0.3.3</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsdwdem2kwl8jsw0zazlpxkulkl25mxscz4vulq34vwchu49af4tpczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5egwjp3" />
    <content type="html">
      In reply to &lt;a href=&#39;/nevent1qqs98jgjhk04s43ap6uhjpjac5x5nvmp38j856traua06dk8dtp4gequcskdd&#39;&gt;nevent1q…skdd&lt;/a&gt;&lt;br/&gt;_________________________&lt;br/&gt;&lt;br/&gt;Build manifest for get_file_hash v0.3.3
    </content>
    <updated>2026-04-03T17:18:49&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs98jgjhk04s43ap6uhjpjac5x5nvmp38j856traua06dk8dtp4geqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5c8hxfh</id>
    
      <title type="html">&amp;lt;?xml version=&amp;#39;1.0&amp;#39; ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs98jgjhk04s43ap6uhjpjac5x5nvmp38j856traua06dk8dtp4geqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5c8hxfh" />
    <content type="html">
      &amp;lt;?xml version=&amp;#39;1.0&amp;#39; encoding=&amp;#39;windows-1252&amp;#39;?&amp;gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Copyright (C) 2017 Christopher R. Field.&lt;br/&gt;&lt;br/&gt;  Licensed under the Apache License, Version 2.0 (the &amp;#34;License&amp;#34;);&lt;br/&gt;  you may not use this file except in compliance with the License.&lt;br/&gt;  You may obtain a copy of the License at&lt;br/&gt;&lt;br/&gt;  &lt;a href=&#34;http://www.apache.org/licenses/LICENSE-2.0&#34;&gt;http://www.apache.org/licenses/LICENSE-2.0&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;  Unless required by applicable law or agreed to in writing, software&lt;br/&gt;  distributed under the License is distributed on an &amp;#34;AS IS&amp;#34; BASIS,&lt;br/&gt;  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&lt;br/&gt;  See the License for the specific language governing permissions and&lt;br/&gt;  limitations under the License.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  The &amp;#34;cargo wix&amp;#34; subcommand provides a variety of predefined variables available&lt;br/&gt;  for customization of this template. The values for each variable are set at&lt;br/&gt;  installer creation time. The following variables are available:&lt;br/&gt;&lt;br/&gt;  TargetTriple      = The rustc target triple name.&lt;br/&gt;  TargetEnv         = The rustc target environment. This is typically either&lt;br/&gt;                      &amp;#34;msvc&amp;#34; or &amp;#34;gnu&amp;#34; depending on the toolchain downloaded and&lt;br/&gt;                      installed.&lt;br/&gt;  TargetVendor      = The rustc target vendor. This is typically &amp;#34;pc&amp;#34;, but Rust&lt;br/&gt;                      does support other vendors, like &amp;#34;uwp&amp;#34;.&lt;br/&gt;  CargoTargetBinDir = The complete path to the directory containing the&lt;br/&gt;                      binaries (exes) to include. The default would be&lt;br/&gt;                      &amp;#34;target\release\&amp;#34;. If an explicit rustc target triple is&lt;br/&gt;                      used, i.e. cross-compiling, then the default path would&lt;br/&gt;                      be &amp;#34;target\&amp;lt;CARGO_TARGET&amp;gt;\&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34;,&lt;br/&gt;                      where &amp;#34;&amp;lt;CARGO_TARGET&amp;gt;&amp;#34; is replaced with the &amp;#34;CargoTarget&amp;#34;&lt;br/&gt;                      variable value and &amp;#34;&amp;lt;CARGO_PROFILE&amp;gt;&amp;#34; is replaced with the&lt;br/&gt;                      value from the &amp;#34;CargoProfile&amp;#34; variable. This can also&lt;br/&gt;                      be overridden manually with the &amp;#34;target-bin-dir&amp;#34; flag.&lt;br/&gt;  CargoTargetDir    = The path to the directory for the build artifacts, i.e.&lt;br/&gt;                      &amp;#34;target&amp;#34;.&lt;br/&gt;  CargoProfile      = The cargo profile used to build the binaries&lt;br/&gt;                      (usually &amp;#34;debug&amp;#34; or &amp;#34;release&amp;#34;).&lt;br/&gt;  Version           = The version for the installer. The default is the&lt;br/&gt;                      &amp;#34;Major.Minor.Fix&amp;#34; semantic versioning number of the Rust&lt;br/&gt;                      package.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;!--&lt;br/&gt;  Please do not remove these pre-processor If-Else blocks. These are used with&lt;br/&gt;  the `cargo wix` subcommand to automatically determine the installation&lt;br/&gt;  destination for 32-bit versus 64-bit installers. Removal of these lines will&lt;br/&gt;  cause installation errors.&lt;br/&gt;--&amp;gt;&lt;br/&gt;&amp;lt;?if $(sys.BUILDARCH) = x64 or $(sys.BUILDARCH) = arm64 ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFiles64Folder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?else ?&amp;gt;&lt;br/&gt;    &amp;lt;?define PlatformProgramFilesFolder = &amp;#34;ProgramFilesFolder&amp;#34; ?&amp;gt;&lt;br/&gt;&amp;lt;?endif ?&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;Wix xmlns=&amp;#39;&lt;a href=&#34;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&#34;&gt;http://schemas.microsoft.com/wix/2006/wi&amp;#39;&amp;gt&lt;/a&gt;;&lt;br/&gt;&lt;br/&gt;    &amp;lt;Product&lt;br/&gt;        Id=&amp;#39;*&amp;#39;&lt;br/&gt;        Name=&amp;#39;get_file_hash&amp;#39;&lt;br/&gt;        UpgradeCode=&amp;#39;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#39;&lt;br/&gt;        Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;        Language=&amp;#39;1033&amp;#39;&lt;br/&gt;        Codepage=&amp;#39;1252&amp;#39;&lt;br/&gt;        Version=&amp;#39;$(var.Version)&amp;#39;&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Package Id=&amp;#39;*&amp;#39;&lt;br/&gt;            Keywords=&amp;#39;Installer&amp;#39;&lt;br/&gt;            Description=&amp;#39;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#39;&lt;br/&gt;            Manufacturer=&amp;#39;gnostr admin@gnostr.org&amp;#39;&lt;br/&gt;            InstallerVersion=&amp;#39;450&amp;#39;&lt;br/&gt;            Languages=&amp;#39;1033&amp;#39;&lt;br/&gt;            Compressed=&amp;#39;yes&amp;#39;&lt;br/&gt;            InstallScope=&amp;#39;perMachine&amp;#39;&lt;br/&gt;            SummaryCodepage=&amp;#39;1252&amp;#39;&lt;br/&gt;            /&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;MajorUpgrade&lt;br/&gt;            Schedule=&amp;#39;afterInstallInitialize&amp;#39;&lt;br/&gt;            DowngradeErrorMessage=&amp;#39;A newer version of [ProductName] is already installed. Setup will now exit.&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Media Id=&amp;#39;1&amp;#39; Cabinet=&amp;#39;media1.cab&amp;#39; EmbedCab=&amp;#39;yes&amp;#39; DiskPrompt=&amp;#39;CD-ROM #1&amp;#39;/&amp;gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;DiskPrompt&amp;#39; Value=&amp;#39;get_file_hash Installation&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Directory Id=&amp;#39;TARGETDIR&amp;#39; Name=&amp;#39;SourceDir&amp;#39;&amp;gt;&lt;br/&gt;            &amp;lt;Directory Id=&amp;#39;$(var.PlatformProgramFilesFolder)&amp;#39; Name=&amp;#39;PFiles&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;Directory Id=&amp;#39;APPLICATIONFOLDER&amp;#39; Name=&amp;#39;get_file_hash&amp;#39;&amp;gt;&lt;br/&gt;                    &lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                      Enabling the license sidecar file in the installer is a four step process:&lt;br/&gt;&lt;br/&gt;                      1. Uncomment the `Component` tag and its contents.&lt;br/&gt;                      2. Change the value for the `Source` attribute in the `File` tag to a path&lt;br/&gt;                         to the file that should be included as the license sidecar file. The path&lt;br/&gt;                         can, and probably should be, relative to this file.&lt;br/&gt;                      3. Change the value for the `Name` attribute in the `File` tag to the&lt;br/&gt;                         desired name for the file when it is installed alongside the `bin` folder&lt;br/&gt;                         in the installation directory. This can be omitted if the desired name is&lt;br/&gt;                         the same as the file name.&lt;br/&gt;                      4. Uncomment the `ComponentRef` tag with the Id attribute value of &amp;#34;License&amp;#34;&lt;br/&gt;                         further down in this file.&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;                    &amp;lt;!--&lt;br/&gt;                    &amp;lt;Component Id=&amp;#39;License&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;File Id=&amp;#39;LicenseFile&amp;#39; Name=&amp;#39;ChangeMe&amp;#39; DiskId=&amp;#39;1&amp;#39; Source=&amp;#39;C:\Path\To\File&amp;#39; KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                    &amp;lt;/Component&amp;gt;&lt;br/&gt;                    --&amp;gt;&lt;br/&gt;&lt;br/&gt;                    &amp;lt;Directory Id=&amp;#39;Bin&amp;#39; Name=&amp;#39;bin&amp;#39;&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;Path&amp;#39; Guid=&amp;#39;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#39; KeyPath=&amp;#39;yes&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;Environment&lt;br/&gt;                                Id=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Name=&amp;#39;PATH&amp;#39;&lt;br/&gt;                                Value=&amp;#39;[Bin]&amp;#39;&lt;br/&gt;                                Permanent=&amp;#39;no&amp;#39;&lt;br/&gt;                                Part=&amp;#39;last&amp;#39;&lt;br/&gt;                                Action=&amp;#39;set&amp;#39;&lt;br/&gt;                                System=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary0&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe0&amp;#39;&lt;br/&gt;                                Name=&amp;#39;get_file_hash.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\get_file_hash.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                        &amp;lt;Component Id=&amp;#39;binary1&amp;#39; Guid=&amp;#39;*&amp;#39;&amp;gt;&lt;br/&gt;                            &amp;lt;File&lt;br/&gt;                                Id=&amp;#39;exe1&amp;#39;&lt;br/&gt;                                Name=&amp;#39;readme.exe&amp;#39;&lt;br/&gt;                                DiskId=&amp;#39;1&amp;#39;&lt;br/&gt;                                Source=&amp;#39;$(var.CargoTargetBinDir)\readme.exe&amp;#39;&lt;br/&gt;                                KeyPath=&amp;#39;yes&amp;#39;/&amp;gt;&lt;br/&gt;                        &amp;lt;/Component&amp;gt;&lt;br/&gt;                    &amp;lt;/Directory&amp;gt;&lt;br/&gt;                &amp;lt;/Directory&amp;gt;&lt;br/&gt;            &amp;lt;/Directory&amp;gt;&lt;br/&gt;        &amp;lt;/Directory&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Feature&lt;br/&gt;            Id=&amp;#39;Binaries&amp;#39;&lt;br/&gt;            Title=&amp;#39;Application&amp;#39;&lt;br/&gt;            Description=&amp;#39;Installs all binaries and the license.&amp;#39;&lt;br/&gt;            Level=&amp;#39;1&amp;#39;&lt;br/&gt;            ConfigurableDirectory=&amp;#39;APPLICATIONFOLDER&amp;#39;&lt;br/&gt;            AllowAdvertise=&amp;#39;no&amp;#39;&lt;br/&gt;            Display=&amp;#39;expand&amp;#39;&lt;br/&gt;            Absent=&amp;#39;disallow&amp;#39;&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Uncomment the following `ComponentRef` tag to add the license&lt;br/&gt;              sidecar file to the installer.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;!--&amp;lt;ComponentRef Id=&amp;#39;License&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary0&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;ComponentRef Id=&amp;#39;binary1&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;            &amp;lt;Feature&lt;br/&gt;                Id=&amp;#39;Environment&amp;#39;&lt;br/&gt;                Title=&amp;#39;PATH Environment Variable&amp;#39;&lt;br/&gt;                Description=&amp;#39;Add the install location of the [ProductName] executable to the PATH system environment variable. This allows the [ProductName] executable to be called from any location.&amp;#39;&lt;br/&gt;                Level=&amp;#39;1&amp;#39;&lt;br/&gt;                Absent=&amp;#39;allow&amp;#39;&amp;gt;&lt;br/&gt;                &amp;lt;ComponentRef Id=&amp;#39;Path&amp;#39;/&amp;gt;&lt;br/&gt;            &amp;lt;/Feature&amp;gt;&lt;br/&gt;        &amp;lt;/Feature&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;SetProperty Id=&amp;#39;ARPINSTALLLOCATION&amp;#39; Value=&amp;#39;[APPLICATIONFOLDER]&amp;#39; After=&amp;#39;CostFinalize&amp;#39;/&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the following `Icon` and `Property` tags to change the product icon.&lt;br/&gt;&lt;br/&gt;          The product icon is the graphic that appears in the Add/Remove&lt;br/&gt;          Programs control panel for the application.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Icon Id=&amp;#39;ProductICO&amp;#39; SourceFile=&amp;#39;wix\Product.ico&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;Property Id=&amp;#39;ARPPRODUCTICON&amp;#39; Value=&amp;#39;ProductICO&amp;#39; /&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;Property Id=&amp;#39;ARPHELPLINK&amp;#39; Value=&amp;#39;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#39;/&amp;gt&lt;/a&gt;;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;UI&amp;gt;&lt;br/&gt;            &amp;lt;UIRef Id=&amp;#39;WixUI_FeatureTree&amp;#39;/&amp;gt;&lt;br/&gt;            &lt;br/&gt;            &amp;lt;!--&lt;br/&gt;              Enabling the EULA dialog in the installer is a three step process:&lt;br/&gt;&lt;br/&gt;                1. Comment out or remove the two `Publish` tags that follow the&lt;br/&gt;                   `WixVariable` tag.&lt;br/&gt;                2. Uncomment the `&amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Path\to\Eula.rft&amp;#39;&amp;gt;` tag further down&lt;br/&gt;                3. Replace the `Value` attribute of the `WixVariable` tag with&lt;br/&gt;                   the path to a RTF file that will be used as the EULA and&lt;br/&gt;                   displayed in the license agreement dialog.&lt;br/&gt;            --&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;WelcomeDlg&amp;#39; Control=&amp;#39;Next&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;CustomizeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;            &amp;lt;Publish Dialog=&amp;#39;CustomizeDlg&amp;#39; Control=&amp;#39;Back&amp;#39; Event=&amp;#39;NewDialog&amp;#39; Value=&amp;#39;WelcomeDlg&amp;#39; Order=&amp;#39;99&amp;#39;&amp;gt;1&amp;lt;/Publish&amp;gt;&lt;br/&gt;&lt;br/&gt;        &amp;lt;/UI&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Enabling the EULA dialog in the installer requires uncommenting&lt;br/&gt;          the following `WixUILicenseRTF` tag and changing the `Value`&lt;br/&gt;          attribute.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!-- &amp;lt;WixVariable Id=&amp;#39;WixUILicenseRtf&amp;#39; Value=&amp;#39;Relative\Path\to\Eula.rtf&amp;#39;/&amp;gt; --&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom banner image across&lt;br/&gt;          the top of each screen. See the WiX Toolset documentation for details&lt;br/&gt;          about customization.&lt;br/&gt;&lt;br/&gt;          The banner BMP dimensions are 493 x 58 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIBannerBmp&amp;#39; Value=&amp;#39;wix\Banner.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;        &lt;br/&gt;        &amp;lt;!--&lt;br/&gt;          Uncomment the next `WixVariable` tag to customize the installer&amp;#39;s&lt;br/&gt;          Graphical User Interface (GUI) and add a custom image to the first&lt;br/&gt;          dialog, or screen. See the WiX Toolset documentation for details about&lt;br/&gt;          customization.&lt;br/&gt;&lt;br/&gt;          The dialog BMP dimensions are 493 x 312 pixels.&lt;br/&gt;        --&amp;gt;&lt;br/&gt;        &amp;lt;!--&amp;lt;WixVariable Id=&amp;#39;WixUIDialogBmp&amp;#39; Value=&amp;#39;wix\Dialog.bmp&amp;#39;/&amp;gt;--&amp;gt;&lt;br/&gt;&lt;br/&gt;    &amp;lt;/Product&amp;gt;&lt;br/&gt;&lt;br/&gt;&amp;lt;/Wix&amp;gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:18:30&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsr6pxesfmu2kr8u2h8pv7y8gja8jlr03ptk2cw70fnyzs9wk5uvlqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52fptgu</id>
    
      <title type="html">use std::process::Command; use std::fs; use sha2::{Digest, ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsr6pxesfmu2kr8u2h8pv7y8gja8jlr03ptk2cw70fnyzs9wk5uvlqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52fptgu" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::fs;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn calculate_sha256(file_path: &amp;amp;str) -&amp;gt; String {&lt;br/&gt;    let content = fs::read(file_path).expect(&amp;#34;Unable to read file&amp;#34;);&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(&amp;amp;content);&lt;br/&gt;    hasher.finalize()&lt;br/&gt;        .iter()&lt;br/&gt;        .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_no_features() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    // Check for the raw hash first&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    // Use a regex-like check for more flexibility with newlines if needed, or refine to exact match&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (no features):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[test]&lt;br/&gt;fn test_get_file_hash_binary_with_nostr_feature() {&lt;br/&gt;    let output = Command::new(&amp;#34;cargo&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;run&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--bin&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;get_file_hash&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;--features&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;nostr&amp;#34;)&lt;br/&gt;        .output()&lt;br/&gt;        .expect(&amp;#34;Failed to execute command&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let stdout = String::from_utf8_lossy(&amp;amp;output.stdout);&lt;br/&gt;    let stderr = String::from_utf8_lossy(&amp;amp;output.stderr);&lt;br/&gt;&lt;br/&gt;    // Assert that the command ran successfully&lt;br/&gt;    assert!(output.status.success(), &amp;#34;Command failed with stderr: {}&amp;#34;, stderr);&lt;br/&gt;&lt;br/&gt;    // Manually calculate the hash of the binary&amp;#39;s source file&lt;br/&gt;    let expected_hash = calculate_sha256(&amp;#34;src/bin/get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains the correct hash&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash), &amp;#34;Output did not contain raw expected hash. Expected: {}, Actual: {}&amp;#34;, expected_hash, stdout);&lt;br/&gt;&lt;br/&gt;    // Then check for the formatted string, including backticks&lt;br/&gt;    let expected_hash_line = format!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, expected_hash);&lt;br/&gt;    assert!(stdout.contains(&amp;amp;expected_hash_line), &amp;#34;Output did not contain expected hash line. Expected line: {}, Actual: {}&amp;#34;, expected_hash_line, stdout);&lt;br/&gt;&lt;br/&gt;    // Assert that the output contains &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    assert!(stdout.contains(&amp;#34;Integrity Verified.&amp;#34;), &amp;#34;Output did not contain &amp;#39;Integrity Verified.&amp;#39;. stdout: {}&amp;#34;, stdout);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Output from get_file_hash binary (with nostr feature):&lt;br/&gt;{}&amp;#34;, stdout);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:18:19&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsyhkmzc7c5jw23pz9nr20wku45vpljuw032v256s76hmjeyfpaj0czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5p6mgas</id>
    
      <title type="html">//! A crate providing the `get_file_hash!` procedural macro. //! ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsyhkmzc7c5jw23pz9nr20wku45vpljuw032v256s76hmjeyfpaj0czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5p6mgas" />
    <content type="html">
      //! A crate providing the `get_file_hash!` procedural macro.&lt;br/&gt;//!&lt;br/&gt;//! This macro allows you to compute the SHA-256 hash of a file at compile time,&lt;br/&gt;//! embedding the resulting hash string directly into your Rust executable.&lt;br/&gt;&lt;br/&gt;pub use get_file_hash_core::get_file_hash;&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `build.rs` at the time of compilation.&lt;br/&gt;pub const BUILD_HASH: &amp;amp;str = env!(&amp;#34;BUILD_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `Cargo.toml` at the time of compilation.&lt;br/&gt;pub const CARGO_TOML_HASH: &amp;amp;str = env!(&amp;#34;CARGO_TOML_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The SHA-256 hash of this crate&amp;#39;s `src/lib.rs` at the time of compilation.&lt;br/&gt;pub const LIB_HASH: &amp;amp;str = env!(&amp;#34;LIB_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The name of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_NAME: &amp;amp;str = env!(&amp;#34;CARGO_PKG_NAME&amp;#34;);&lt;br/&gt;&lt;br/&gt;/// The version of the package as specified in Cargo.toml.&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git commit hash of the repository at the time of compilation.&lt;br/&gt;pub const GIT_COMMIT_HASH: &amp;amp;str = env!(&amp;#34;GIT_COMMIT_HASH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;/// The git branch of the repository at the time of compilation.&lt;br/&gt;pub const GIT_BRANCH: &amp;amp;str = env!(&amp;#34;GIT_BRANCH&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;    use super::*;&lt;br/&gt;&lt;br/&gt;    /// Verifies that the exported CARGO_TOML_HASH is not empty.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_injected_hash_exists() {&lt;br/&gt;        assert!(!BUILD_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified build.rs Hash:&lt;br/&gt;{}&amp;#34;, BUILD_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_TOML_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Cargo.toml Hash:&lt;br/&gt;{}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!LIB_HASH.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified src/lib.rs Hash:\n{}&amp;#34;, LIB_HASH);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_NAME.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Name:\n{}&amp;#34;, CARGO_PKG_NAME);&lt;br/&gt;&lt;br/&gt;        assert!(!CARGO_PKG_VERSION.is_empty());&lt;br/&gt;        println!(&amp;#34;Verified Package Version:\n{}&amp;#34;, CARGO_PKG_VERSION);&lt;br/&gt;&lt;br/&gt;        #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;        {&lt;br/&gt;            assert!(!GIT_COMMIT_HASH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Commit Hash:\n{}&amp;#34;, GIT_COMMIT_HASH);&lt;br/&gt;&lt;br/&gt;            assert!(!GIT_BRANCH.is_empty());&lt;br/&gt;            println!(&amp;#34;Verified Git Branch:\n{}&amp;#34;, GIT_BRANCH);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// Tests that the `get_file_hash!` macro correctly computes the SHA-256&lt;br/&gt;    /// hash of `lib.rs` and that it matches a manually computed hash of the&lt;br/&gt;    /// same file.&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_lib_hash() {&lt;br/&gt;        let file_content = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(file_content);&lt;br/&gt;        let expected_hash = hasher&lt;br/&gt;            .finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        let actual_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        assert_eq!(actual_hash, expected_hash);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:18:09&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsfhuglywlkwt4emeutcdx89ku6mrj4rkdggpmz2aecrnheaf4hxcgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53pqxlc</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsfhuglywlkwt4emeutcdx89ku6mrj4rkdggpmz2aecrnheaf4hxcgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53pqxlc" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-03T17:17:57&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs9tfv5f2znq8rl2fh0tz7nzmmajsuqpsrgpkyjx267kt6r2jt2a2szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn590hdd3</id>
    
      <title type="html">use std::process::Command; use std::path::PathBuf; #[cfg(feature ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs9tfv5f2znq8rl2fh0tz7nzmmajsuqpsrgpkyjx267kt6r2jt2a2szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn590hdd3" />
    <content type="html">
      use std::process::Command;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use nostr_sdk::prelude::{*, EventBuilder, Tag, Kind};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use serde_json::json;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use csv::ReaderBuilder;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use ::url::Url;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::keys::{KeyPackage, PublicKeyPackage, SecretShare};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::round1::{SigningCommitments, SigningNonces};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub use frost_secp256k1_tr as frost_bip340;&lt;br/&gt;&lt;br/&gt;pub mod frost_mailbox_logic;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;pub const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;pub const DEFAULT_GNOSTR_KEY: &amp;amp;str = &amp;#34;e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855&amp;#34;;&lt;br/&gt;pub const DEFAULT_PICTURE_URL: &amp;amp;str = &amp;#34;&lt;a href=&#34;https://avatars.githubusercontent.com/u/135379339?s=400&amp;amp;u=11cb72cccbc2b13252867099546074c50caef1ae&amp;amp;v=4&amp;#34&#34;&gt;https://avatars.githubusercontent.com/u/135379339?s=400&amp;amp;u=11cb72cccbc2b13252867099546074c50caef1ae&amp;amp;v=4&amp;#34&lt;/a&gt;;;&lt;br/&gt;pub const DEFAULT_BANNER_URL: &amp;amp;str = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/gnostr-org/gnostr-icons/refs/heads/master/banner/1024x341.png&amp;#34&#34;&gt;https://raw.githubusercontent.com/gnostr-org/gnostr-icons/refs/heads/master/banner/1024x341.png&amp;#34&lt;/a&gt;;;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;const ONLINE_RELAYS_GPS_CSV: &amp;amp;[u8] = include_bytes!(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub fn get_relay_urls() -&amp;gt; Vec&amp;lt;String&amp;gt; {&lt;br/&gt;    let content = String::from_utf8_lossy(ONLINE_RELAYS_GPS_CSV);&lt;br/&gt;    let mut rdr = ReaderBuilder::new()&lt;br/&gt;        .has_headers(true)&lt;br/&gt;        .from_reader(content.as_bytes());&lt;br/&gt;&lt;br/&gt;    rdr.records()&lt;br/&gt;        .filter_map(|result| {&lt;br/&gt;            match result {&lt;br/&gt;                Ok(record) =&amp;gt; {&lt;br/&gt;                    record.get(0).and_then(|url_str| {&lt;br/&gt;                        let full_url_str = if url_str.contains(&amp;#34;://&amp;#34;) {&lt;br/&gt;                            url_str.to_string()&lt;br/&gt;                        } else {&lt;br/&gt;                            format!(&amp;#34;wss://{}&amp;#34;, url_str)&lt;br/&gt;                        };&lt;br/&gt;                        match Url::parse(&amp;amp;full_url_str) {&lt;br/&gt;                            Ok(url) if url.scheme() == &amp;#34;wss&amp;#34; =&amp;gt; Some(url.to_string()),&lt;br/&gt;                            _ =&amp;gt; {&lt;br/&gt;                                eprintln!(&amp;#34;Warning: Invalid or unsupported relay URL scheme: {}&amp;#34;, full_url_str);&lt;br/&gt;                                None&lt;br/&gt;                            }&lt;br/&gt;                        }&lt;br/&gt;                    })&lt;br/&gt;                },&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    eprintln!(&amp;#34;Error reading CSV record: {}&amp;#34;, e);&lt;br/&gt;                    None&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        })&lt;br/&gt;        .collect()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Computes the SHA-256 hash of the specified file at compile time.&lt;br/&gt;///&lt;br/&gt;/// This macro takes a string literal representing a file path, reads the file&amp;#39;s bytes&lt;br/&gt;/// at compile time, computes its SHA-256 hash, and returns the hash as a hex-encoded `String`.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```rust&lt;br/&gt;/// use get_file_hash_core::get_file_hash;&lt;br/&gt;/// use sha2::{Digest, Sha256};&lt;br/&gt;///&lt;br/&gt;/// let hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;/// println!(&amp;#34;Hash: {}&amp;#34;, hash);&lt;br/&gt;/// ```&lt;br/&gt;&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! get_file_hash {&lt;br/&gt;    ($file_path:expr) =&amp;gt; {{&lt;br/&gt;        let bytes = include_bytes!($file_path);&lt;br/&gt;        let mut hasher = Sha256::new();&lt;br/&gt;        hasher.update(bytes);&lt;br/&gt;        let result = hasher.finalize();&lt;br/&gt;&lt;br/&gt;        // Convert the GenericArray to a hex string&lt;br/&gt;        result&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;()&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Computes the SHA-256 hash of the specified file at compile time and uses it as a Nostr private key.&lt;br/&gt;///&lt;br/&gt;/// This macro takes a string literal representing a file path, computes its SHA-256 hash,&lt;br/&gt;/// and returns a `nostr::Keys` object derived from this hash.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```rust&lt;br/&gt;/// use get_file_hash_core::file_hash_as_nostr_private_key;&lt;br/&gt;/// use sha2::{Digest, Sha256};&lt;br/&gt;/// use nostr_sdk::prelude::ToBech32;&lt;br/&gt;///&lt;br/&gt;/// let keys = file_hash_as_nostr_private_key!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;/// println!(&amp;#34;Public Key: {}&amp;#34;, keys.public_key().to_bech32().unwrap());&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! file_hash_as_nostr_private_key {&lt;br/&gt;    ($file_path:expr) =&amp;gt; {{&lt;br/&gt;        let hash_hex = $crate::get_file_hash!($file_path);&lt;br/&gt;        nostr_sdk::Keys::parse(&amp;amp;hash_hex).expect(&amp;#34;Failed to create Nostr Keys from file hash&amp;#34;)&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 repository announcement event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, project details, a clone URL, and a file path.&lt;br/&gt;/// It computes the SHA-256 hash of the file at compile time to use as the &amp;#34;earliest unique commit&amp;#34; (EUC),&lt;br/&gt;/// and then publishes a Kind 30617 event.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::repository_announcement;&lt;br/&gt;/// use get_file_hash_core::get_file_hash;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;/// use sha2::{Digest, Sha256};&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let project_name = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let description = &amp;#34;A fantastic new project.&amp;#34;;&lt;br/&gt;///     let clone_url = &amp;#34;git@github.com:user/my-awesome-repo.git&amp;#34;;&lt;br/&gt;///&lt;br/&gt;///     repository_announcement!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         project_name,&lt;br/&gt;///         description,&lt;br/&gt;///         clone_url,&lt;br/&gt;///         &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;///         None&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! repository_announcement {&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $project_name:expr, $description:expr, $clone_url:expr, $file_for_euc:expr) =&amp;gt; {{&lt;br/&gt;        let euc_hash = $crate::get_file_hash!($file_for_euc);&lt;br/&gt;        // The &amp;#39;d&amp;#39; tag value should be unique for the repository. Using the project_name for simplicity.&lt;br/&gt;        let d_tag_value = $project_name;&lt;br/&gt;        $crate::publish_repository_announcement_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $project_name,&lt;br/&gt;            $description,&lt;br/&gt;            $clone_url,&lt;br/&gt;            &amp;amp;euc_hash,&lt;br/&gt;            d_tag_value,&lt;br/&gt;            None,&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $project_name:expr, $description:expr, $clone_url:expr, $file_for_euc:expr, $build_manifest_event_id:expr) =&amp;gt; {{&lt;br/&gt;        let euc_hash = $crate::get_file_hash!($file_for_euc);&lt;br/&gt;        let d_tag_value = $project_name;&lt;br/&gt;        $crate::publish_repository_announcement_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $project_name,&lt;br/&gt;            $description,&lt;br/&gt;            $clone_url,&lt;br/&gt;            &amp;amp;euc_hash,&lt;br/&gt;            d_tag_value,&lt;br/&gt;            $build_manifest_event_id, // Correct: Pass directly&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 patch event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, the repository&amp;#39;s d-tag value,&lt;br/&gt;/// the commit ID the patch applies to, and the path to the patch file.&lt;br/&gt;/// The content of the patch file is included directly in the event.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::publish_patch;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let d_tag = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;///&lt;br/&gt;///     publish_patch!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         d_tag,&lt;br/&gt;///         commit_id,&lt;br/&gt;///         &amp;#34;lib.rs&amp;#34; // Use an existing file for the patch content&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! publish_patch {&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $patch_file_path:expr) =&amp;gt; {{&lt;br/&gt;        let patch_content = include_str!($patch_file_path);&lt;br/&gt;        $crate::publish_patch_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $commit_id,&lt;br/&gt;            patch_content,&lt;br/&gt;            None, // Pass None for build_manifest_event_id&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $patch_file_path:expr, $build_manifest_event_id:expr) =&amp;gt; {{&lt;br/&gt;        let patch_content = include_str!($patch_file_path);&lt;br/&gt;        $crate::publish_patch_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $commit_id,&lt;br/&gt;            patch_content,&lt;br/&gt;            $build_manifest_event_id, // Pass directly, macro arg should be Option&amp;lt;&amp;amp;EventId&amp;gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 pull request event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, the repository&amp;#39;s d-tag value,&lt;br/&gt;/// the commit ID of the pull request, a clone URL where the work can be fetched,&lt;br/&gt;/// and an optional title for the pull request.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::publish_pull_request;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let d_tag = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;///     let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;///     let title = Some(&amp;#34;Feat: Add new awesome feature&amp;#34;);&lt;br/&gt;///&lt;br/&gt;///     publish_pull_request!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         d_tag,&lt;br/&gt;///         commit_id,&lt;br/&gt;///         clone_url,&lt;br/&gt;///         title,&lt;br/&gt;///         None&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! publish_pull_request {&lt;br/&gt;    // 5 args: No title, no build_manifest_event_id&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $clone_url:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_pull_request_event(&lt;br/&gt;            $keys, $relay_urls, $d_tag_value, $commit_id, $clone_url,&lt;br/&gt;            None, // title: Option&amp;lt;&amp;amp;str&amp;gt;&lt;br/&gt;            None, // build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;&lt;br/&gt;    // 6 args: With title (Option&amp;lt;&amp;amp;str&amp;gt;), no build_manifest_event_id&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $clone_url:expr, $title:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_pull_request_event(&lt;br/&gt;            $keys, $relay_urls, $d_tag_value, $commit_id, $clone_url,&lt;br/&gt;            $title, // title: Option&amp;lt;&amp;amp;str&amp;gt;&lt;br/&gt;            None, // build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;&lt;br/&gt;    // 7 args: With title (Option&amp;lt;&amp;amp;str&amp;gt;), with build_manifest_event_id (Option&amp;lt;&amp;amp;EventId&amp;gt;)&lt;br/&gt;    // This needs to be before the 6-arg arm that passes a single Option for build_manifest_event_id if it&amp;#39;s not None.&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $clone_url:expr, $title:expr, $build_manifest_event_id:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_pull_request_event(&lt;br/&gt;            $keys, $relay_urls, $d_tag_value, $commit_id, $clone_url,&lt;br/&gt;            $title, // title: Option&amp;lt;&amp;amp;str&amp;gt;&lt;br/&gt;            $build_manifest_event_id, // build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;&lt;br/&gt;    // 6 args: No title, with build_manifest_event_id (Option&amp;lt;&amp;amp;EventId&amp;gt;)&lt;br/&gt;    // This must be after the 7-arg arm to avoid ambiguity.&lt;br/&gt;    // The example needs to explicitly pass None for title.&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $commit_id:expr, $clone_url:expr, _none_title:tt, $build_manifest_event_id:expr) =&amp;gt; {{ // _none_title as tt to match None&lt;br/&gt;        $crate::publish_pull_request_event(&lt;br/&gt;            $keys, $relay_urls, $d_tag_value, $commit_id, $clone_url,&lt;br/&gt;            None, // title: Option&amp;lt;&amp;amp;str&amp;gt;&lt;br/&gt;            $build_manifest_event_id, // build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 PR update event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, the repository&amp;#39;s d-tag value,&lt;br/&gt;/// the event ID of the original pull request, the new commit ID,&lt;br/&gt;/// and the new clone URL.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::publish_pr_update;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;/// use nostr_sdk::EventId;&lt;br/&gt;/// use std::str::FromStr;&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let d_tag = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;///     let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;///     let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;///&lt;br/&gt;///     publish_pr_update!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         d_tag,&lt;br/&gt;///         &amp;amp;pr_event_id,&lt;br/&gt;///         updated_commit_id,&lt;br/&gt;///         updated_clone_url&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! publish_pr_update {&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $pr_event_id:expr, $updated_commit_id:expr, $updated_clone_url:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_pr_update_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $pr_event_id,&lt;br/&gt;            $updated_commit_id,&lt;br/&gt;            $updated_clone_url,&lt;br/&gt;            None, // Pass None for build_manifest_event_id&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $pr_event_id:expr, $updated_commit_id:expr, $updated_clone_url:expr, $build_manifest_event_id:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_pr_update_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $pr_event_id,&lt;br/&gt;            $updated_commit_id,&lt;br/&gt;            $updated_clone_url,&lt;br/&gt;            $build_manifest_event_id,&lt;br/&gt;&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 repository state event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, the repository&amp;#39;s d-tag value,&lt;br/&gt;/// the branch name, and the commit ID for that branch.&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::publish_repository_state;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let d_tag = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;///     let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;///&lt;br/&gt;///     publish_repository_state!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         d_tag,&lt;br/&gt;///         branch_name,&lt;br/&gt;///         commit_id&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! publish_repository_state {&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $branch_name:expr, $commit_id:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_repository_state_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $branch_name,&lt;br/&gt;            $commit_id,&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Publishes a NIP-34 issue event to Nostr relays.&lt;br/&gt;///&lt;br/&gt;/// This macro takes Nostr keys, relay URLs, the repository&amp;#39;s d-tag value,&lt;br/&gt;/// a unique issue ID, the issue&amp;#39;s title, and its content (markdown).&lt;br/&gt;///&lt;br/&gt;/// # Examples&lt;br/&gt;///&lt;br/&gt;/// ```no_run&lt;br/&gt;/// use get_file_hash_core::publish_issue;&lt;br/&gt;/// use nostr_sdk::Keys;&lt;br/&gt;///&lt;br/&gt;/// #[tokio::main]&lt;br/&gt;/// async fn main() {&lt;br/&gt;///     let keys = Keys::generate();&lt;br/&gt;///     let relay_urls = vec![&amp;#34;wss://relay.damus.io&amp;#34;.to_string()];&lt;br/&gt;///     let d_tag = &amp;#34;my-awesome-repo&amp;#34;;&lt;br/&gt;///     let issue_id = &amp;#34;123&amp;#34;;&lt;br/&gt;///     let title = &amp;#34;Bug: Fix authentication flow&amp;#34;;&lt;br/&gt;///     let content = &amp;#34;The authentication flow is currently broken when users try to log in with invalid credentials. It crashes instead of showing an error message.&amp;#34;;&lt;br/&gt;///&lt;br/&gt;///     publish_issue!(&lt;br/&gt;///         &amp;amp;keys,&lt;br/&gt;///         &amp;amp;relay_urls,&lt;br/&gt;///         d_tag,&lt;br/&gt;///         issue_id,&lt;br/&gt;///         title,&lt;br/&gt;///         content&lt;br/&gt;///     );&lt;br/&gt;/// }&lt;br/&gt;/// ```&lt;br/&gt;/// ```&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[macro_export]&lt;br/&gt;macro_rules! publish_issue {&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $issue_id:expr, $title:expr, $content:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_issue_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $issue_id,&lt;br/&gt;            $title,&lt;br/&gt;            $content,&lt;br/&gt;            None, // Pass None for build_manifest_event_id&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;    ($keys:expr, $relay_urls:expr, $d_tag_value:expr, $issue_id:expr, $title:expr, $content:expr, $build_manifest_event_id:expr) =&amp;gt; {{&lt;br/&gt;        $crate::publish_issue_event(&lt;br/&gt;            $keys,&lt;br/&gt;            $relay_urls,&lt;br/&gt;            $d_tag_value,&lt;br/&gt;            $issue_id,&lt;br/&gt;            $title,&lt;br/&gt;            $content,&lt;br/&gt;            $build_manifest_event_id, // Pass Option&amp;lt;&amp;amp;EventId&amp;gt; directly&lt;br/&gt;        ).await;&lt;br/&gt;    }};&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn get_git_tracked_files(dir: &amp;amp;PathBuf) -&amp;gt; Vec&amp;lt;String&amp;gt; {&lt;br/&gt;    match Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;        .arg(&amp;#34;ls-files&amp;#34;)&lt;br/&gt;        .current_dir(dir)&lt;br/&gt;        .stdout(std::process::Stdio::piped())&lt;br/&gt;        .stderr(std::process::Stdio::null())&lt;br/&gt;        .output()&lt;br/&gt;    {&lt;br/&gt;        Ok(output) if output.status.success() &amp;amp;&amp;amp; !output.stdout.is_empty() =&amp;gt; {&lt;br/&gt;            String::from_utf8_lossy(&amp;amp;output.stdout)&lt;br/&gt;                .lines()&lt;br/&gt;                .filter_map(|line| Some(String::from(line)))&lt;br/&gt;                .collect()&lt;br/&gt;        }&lt;br/&gt;        Ok(output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=git ls-files failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     output.status, String::from_utf8_lossy(&amp;amp;output.stderr));&lt;br/&gt;            Vec::new()&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to execute git ls-files: {}&amp;#34;, e);&lt;br/&gt;            Vec::new()&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_metadata_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    picture_url: &amp;amp;str,&lt;br/&gt;    banner_url: &amp;amp;str,&lt;br/&gt;    file_path_str: &amp;amp;str,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for metadata {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let metadata_json = json!({&lt;br/&gt;        &amp;#34;picture&amp;#34;: picture_url,&lt;br/&gt;        &amp;#34;banner&amp;#34;: banner_url,&lt;br/&gt;        &amp;#34;name&amp;#34;: file_path_str,&lt;br/&gt;        &amp;#34;about&amp;#34;: format!(&amp;#34;Metadata for file event: {}&amp;#34;, file_path_str),&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    let metadata = serde_json::from_str::&amp;lt;nostr_sdk::Metadata&amp;gt;(&amp;amp;metadata_json.to_string())&lt;br/&gt;        .expect(&amp;#34;Failed to parse metadata JSON&amp;#34;);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(EventBuilder::metadata(&amp;amp;metadata)).await {&lt;br/&gt;        Ok(_event_id) =&amp;gt; {&lt;br/&gt;            //println!(&amp;#34;cargo:warning=Published Nostr metadata event for {}: {:?}&amp;#34;, file_path_str, event_id);&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr metadata event for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_repository_announcement_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    project_name: &amp;amp;str,&lt;br/&gt;    description: &amp;amp;str,&lt;br/&gt;    clone_url: &amp;amp;str,&lt;br/&gt;    euc: &amp;amp;str, // Earliest Unique Commit hash&lt;br/&gt;    d_tag_value: &amp;amp;str, // d-tag value&lt;br/&gt;    build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for repository announcement {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, project_name]).expect(&amp;#34;Failed to create name tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;description&amp;#34;, description]).expect(&amp;#34;Failed to create description tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;clone&amp;#34;, clone_url]).expect(&amp;#34;Failed to create clone tag&amp;#34;),&lt;br/&gt;        Tag::custom(&amp;#34;euc&amp;#34;.into(), vec![euc.to_string()]),&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // NIP-33 d-tag&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    if let Some(event_id) = build_manifest_event_id {&lt;br/&gt;        tags.push(Tag::event(*event_id));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(30617), // NIP-34 Repository Announcement kind&lt;br/&gt;        &amp;#34;&amp;#34;, // Content is empty for repository announcement&lt;br/&gt;    ).tags(tags);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 Repository Announcement for {}. Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, project_name, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 Repository Announcement for {}: {}&amp;#34;, project_name, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_patch_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    d_tag_value: &amp;amp;str,&lt;br/&gt;    commit_id: &amp;amp;str,&lt;br/&gt;    patch_content: &amp;amp;str,&lt;br/&gt;    build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for patch {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // Repository d-tag&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, commit_id]).expect(&amp;#34;Failed to create commit tag&amp;#34;),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    if let Some(event_id) = build_manifest_event_id {&lt;br/&gt;        tags.push(Tag::event(*event_id));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(1617), // NIP-34 Patch kind&lt;br/&gt;        patch_content,&lt;br/&gt;    ).tags(tags);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 Patch event for commit {}. Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, commit_id, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 Patch event for commit {}: {}&amp;#34;, commit_id, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_pull_request_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    d_tag_value: &amp;amp;str,&lt;br/&gt;    commit_id: &amp;amp;str,&lt;br/&gt;    clone_url: &amp;amp;str,&lt;br/&gt;    title: Option&amp;lt;&amp;amp;str&amp;gt;,&lt;br/&gt;    build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for pull request {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // Repository d-tag&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, commit_id]).expect(&amp;#34;Failed to create commit tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;clone&amp;#34;, clone_url]).expect(&amp;#34;Failed to create clone tag&amp;#34;),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    if let Some(t) = title {&lt;br/&gt;        tags.push(Tag::parse([&amp;#34;title&amp;#34;, t]).expect(&amp;#34;Failed to create title tag&amp;#34;));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    if let Some(event_id) = build_manifest_event_id {&lt;br/&gt;        tags.push(Tag::event(*event_id));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(1618), // NIP-34 Pull Request kind&lt;br/&gt;        &amp;#34;&amp;#34;, // Content can be empty or a description for the PR&lt;br/&gt;    ).tags(tags);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 Pull Request event for commit {}. Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, commit_id, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 Pull Request event for commit {}: {}&amp;#34;, commit_id, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_pr_update_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    d_tag_value: &amp;amp;str,&lt;br/&gt;    pr_event_id: &amp;amp;EventId,&lt;br/&gt;    updated_commit_id: &amp;amp;str,&lt;br/&gt;    updated_clone_url: &amp;amp;str,&lt;br/&gt;    build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for PR update {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // Repository d-tag&lt;br/&gt;        Tag::parse([&amp;#34;p&amp;#34;, pr_event_id.to_string().as_str()]).expect(&amp;#34;Failed to create PR event ID tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, updated_commit_id]).expect(&amp;#34;Failed to create updated commit ID tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;clone&amp;#34;, updated_clone_url]).expect(&amp;#34;Failed to create updated clone URL tag&amp;#34;),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    if let Some(event_id) = build_manifest_event_id {&lt;br/&gt;        tags.push(Tag::event(*event_id));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(1619), // NIP-34 PR Update kind&lt;br/&gt;        &amp;#34;&amp;#34;, // Content is empty for PR update&lt;br/&gt;    ).tags(tags);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 PR Update event for PR {} (raw: {:?}). Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, pr_event_id.to_bech32().unwrap(), pr_event_id, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 PR Update event for PR {}: {}&amp;#34;, pr_event_id.to_string(), e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_repository_state_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    d_tag_value: &amp;amp;str,&lt;br/&gt;    branch_name: &amp;amp;str,&lt;br/&gt;    commit_id: &amp;amp;str,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for repository state {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(30618), // NIP-34 Repository State kind&lt;br/&gt;        &amp;#34;&amp;#34;, // Content is empty for repository state&lt;br/&gt;    ).tags(vec![&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // Repository d-tag&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, branch_name]).expect(&amp;#34;Failed to create branch name tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, commit_id]).expect(&amp;#34;Failed to create commit ID tag&amp;#34;),&lt;br/&gt;    ]);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 Repository State event for branch {} (commit {}). Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, branch_name, commit_id, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 Repository State event for branch {} (commit {}): {}&amp;#34;, branch_name, commit_id, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub async fn publish_issue_event(&lt;br/&gt;    keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;[String],&lt;br/&gt;    d_tag_value: &amp;amp;str,&lt;br/&gt;    issue_id: &amp;amp;str, // Unique identifier for the issue&lt;br/&gt;    title: &amp;amp;str,&lt;br/&gt;    content: &amp;amp;str,&lt;br/&gt;    build_manifest_event_id: Option&amp;lt;&amp;amp;EventId&amp;gt;,&lt;br/&gt;) {&lt;br/&gt;    let client = nostr_sdk::Client::new(keys.clone());&lt;br/&gt;&lt;br/&gt;    for relay_url in relay_urls {&lt;br/&gt;        if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to add relay for issue {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    client.connect().await;&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::custom(&amp;#34;d&amp;#34;.into(), vec![d_tag_value.to_string()]), // Repository d-tag&lt;br/&gt;        Tag::parse([&amp;#34;i&amp;#34;, issue_id]).expect(&amp;#34;Failed to create issue ID tag&amp;#34;),&lt;br/&gt;        Tag::parse([&amp;#34;title&amp;#34;, title]).expect(&amp;#34;Failed to create title tag&amp;#34;),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    if let Some(event_id) = build_manifest_event_id {&lt;br/&gt;        tags.push(Tag::event(*event_id));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(&lt;br/&gt;        Kind::Custom(1621), // NIP-34 Issue kind&lt;br/&gt;        content,&lt;br/&gt;    ).tags(tags);&lt;br/&gt;&lt;br/&gt;    match client.send_event_builder(event_builder).await {&lt;br/&gt;        Ok(event_id) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published NIP-34 Issue event for issue {} ({}). Event ID (raw): {:?}, Event ID (bech32): {}&amp;#34;, issue_id, title, event_id, event_id.to_bech32().unwrap());&lt;br/&gt;        }&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish NIP-34 Issue event for issue {} ({}): {}&amp;#34;, issue_id, title, e);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;pub fn generate_frost_keys(&lt;br/&gt;    max_signers: u16,&lt;br/&gt;    min_signers: u16,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(BTreeMap&amp;lt;frost::Identifier, SecretShare&amp;gt;, PublicKeyPackage), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {                let mut rng = thread_rng();&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;    Ok((shares, pubkey_package))&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    pub fn create_frost_commitment(&lt;br/&gt;    secret_share: &amp;amp;SecretShare,&lt;br/&gt;    ) -&amp;gt; (SigningNonces, SigningCommitments) {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    frost::round1::commit(secret_share.signing_share(), &amp;amp;mut rng)&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    pub fn create_signing_package(&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, SigningCommitments&amp;gt;,&lt;br/&gt;    message: &amp;amp;[u8],&lt;br/&gt;    ) -&amp;gt; SigningPackage {&lt;br/&gt;    frost::SigningPackage::new(commitments, message)&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    pub fn generate_signature_share(&lt;br/&gt;    signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    nonces: &amp;amp;SigningNonces,&lt;br/&gt;    secret_share: &amp;amp;SecretShare,&lt;br/&gt;    ) -&amp;gt; Result&amp;lt;SignatureShare, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let key_package: KeyPackage = secret_share.clone().try_into()?;&lt;br/&gt;    Ok(frost::round2::sign(signing_package, nonces, &amp;amp;key_package)?)&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    pub fn aggregate_signature_shares(&lt;br/&gt;    signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    signature_shares: &amp;amp;BTreeMap&amp;lt;frost::Identifier, SignatureShare&amp;gt;,&lt;br/&gt;    pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;    ) -&amp;gt; Result&amp;lt;frost_secp256k1_tr::Signature, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    Ok(frost::aggregate(signing_package, signature_shares, pubkey_package)?)&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    pub fn verify_frost_signature(&lt;br/&gt;    group_public_key: &amp;amp;frost_secp256k1_tr::VerifyingKey,&lt;br/&gt;    message: &amp;amp;[u8],&lt;br/&gt;    signature: &amp;amp;frost_secp256k1_tr::Signature,&lt;br/&gt;    ) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    Ok(group_public_key.verify(message, signature)?)&lt;br/&gt;    }&lt;br/&gt;#[cfg(test)]&lt;br/&gt;mod tests {&lt;br/&gt;	use serial_test::serial;&lt;br/&gt;&lt;br/&gt;	use std::collections::BTreeMap;&lt;br/&gt;    use std::fs::File;&lt;br/&gt;    use std::io::Write;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use tempfile;&lt;br/&gt;    use super::get_git_tracked_files;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    use super::frost;&lt;br/&gt;        use std::process::Command;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    // Test for get_file_hash! macro&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_file_hash() {&lt;br/&gt;        let dir = tempfile::tempdir().unwrap();&lt;br/&gt;        let file_path = dir.path().join(&amp;#34;test_file.txt&amp;#34;);&lt;br/&gt;        let content = &amp;#34;Hello, world!&amp;#34;;&lt;br/&gt;        File::create(&amp;amp;file_path).unwrap().write_all(content.as_bytes()).unwrap();&lt;br/&gt;&lt;br/&gt;        // The macro expects a string literal, so we need to construct the path at compile time.&lt;br/&gt;        // This is a limitation for testing, normally you&amp;#39;d use it with a known file.&lt;br/&gt;        // For testing, we&amp;#39;ll manually verify a file known to be in the project.&lt;br/&gt;        // Let&amp;#39;s test `lib.rs` itself for a more realistic scenario.&lt;br/&gt;        let macro_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // We will assert on a known file within the crate.&lt;br/&gt;        let bytes = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        let mut hasher_manual = Sha256::new();&lt;br/&gt;        hasher_manual.update(bytes);&lt;br/&gt;        let expected_hash_lib_rs = hasher_manual.finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        assert_eq!(macro_hash, expected_hash_lib_rs);&lt;br/&gt;&lt;br/&gt;        // Test with another known file, e.g., Cargo.toml of the core crate&lt;br/&gt;        let cargo_toml_hash = get_file_hash!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;        let cargo_toml_bytes = include_bytes!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;        let mut cargo_toml_hasher = Sha256::new();&lt;br/&gt;        cargo_toml_hasher.update(cargo_toml_bytes);&lt;br/&gt;        let expected_cargo_toml_hash = cargo_toml_hasher.finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;        assert_eq!(cargo_toml_hash, expected_cargo_toml_hash);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_git_tracked_files() {&lt;br/&gt;        let dir = tempfile::tempdir().unwrap();&lt;br/&gt;        let repo_path = dir.path();&lt;br/&gt;&lt;br/&gt;        // Initialize a git repository&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;init&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to initialize git repo&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // Create some files&lt;br/&gt;        let file1_path = repo_path.join(&amp;#34;file1.txt&amp;#34;);&lt;br/&gt;        File::create(&amp;amp;file1_path).unwrap().write_all(b&amp;#34;content1&amp;#34;).unwrap();&lt;br/&gt;        let file2_path = repo_path.join(&amp;#34;file2.txt&amp;#34;);&lt;br/&gt;        File::create(&amp;amp;file2_path).unwrap().write_all(b&amp;#34;content2&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        // Add and commit files&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;add&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;.&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to git add files&amp;#34;);&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;commit&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;-m&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;Initial commit&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to git commit&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let tracked_files = get_git_tracked_files(&amp;amp;repo_path.to_path_buf());&lt;br/&gt;        assert_eq!(tracked_files.len(), 2);&lt;br/&gt;        assert!(tracked_files.contains(&amp;amp;&amp;#34;file1.txt&amp;#34;.to_string()));&lt;br/&gt;        assert!(tracked_files.contains(&amp;amp;&amp;#34;file2.txt&amp;#34;.to_string()));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    // #[test]&lt;br/&gt;    // fn test_file_hash_as_nostr_private_key() {&lt;br/&gt;    //     use super::file_hash_as_nostr_private_key;&lt;br/&gt;    //     // use std::fs::{File, remove_file};&lt;br/&gt;    //     // use std::io::Write;&lt;br/&gt;    //     // use tempfile::tempdir; // Not needed as we&amp;#39;re using a literal path&lt;br/&gt;    //     use nostr_sdk::prelude::ToBech32;&lt;br/&gt;&lt;br/&gt;    //     let file_path = PathBuf::from(&amp;#34;test_nostr_file_for_macro.txt&amp;#34;);&lt;br/&gt;    //     let content = &amp;#34;Nostr test content!&amp;#34;;&lt;br/&gt;    //     File::create(&amp;amp;file_path).unwrap().write_all(content.as_bytes()).unwrap();&lt;br/&gt;&lt;br/&gt;    //     let keys = file_hash_as_nostr_private_key!(&amp;#34;test_nostr_file_for_macro.txt&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //     assert!(!keys.public_key().to_bech32().unwrap().is_empty());&lt;br/&gt;&lt;br/&gt;    //     remove_file(&amp;amp;file_path).unwrap();&lt;br/&gt;    // }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_metadata_event_tr() {&lt;br/&gt;        use super::publish_metadata_event;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let picture_url = super::DEFAULT_PICTURE_URL;&lt;br/&gt;        let banner_url = super::DEFAULT_BANNER_URL;&lt;br/&gt;        let file_path_str = &amp;#34;test_file.txt&amp;#34;;&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the function doesn&amp;#39;t panic&lt;br/&gt;        // and goes through its execution path.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        let relay_urls = super::get_relay_urls();&lt;br/&gt;        publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            picture_url,&lt;br/&gt;            banner_url,&lt;br/&gt;            file_path_str,&lt;br/&gt;        ).await;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    #[serial]&lt;br/&gt;    async fn test_repository_announcement_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::{Keys, EventId};&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let project_name = &amp;#34;test-nip34-repo&amp;#34;;&lt;br/&gt;        let description = &amp;#34;A test repository for NIP-34 announcements.&amp;#34;;&lt;br/&gt;        let clone_url = &amp;#34;git@example.com:test/test-nip34-repo.git&amp;#34;;&lt;br/&gt;        let _dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;        let _file_for_euc = &amp;#34;Cargo.toml&amp;#34;; // Use a known file in the project, as required by include_bytes!&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_announcement_picture.jpg&amp;#34&#34;&gt;https://example.com/test_repo_announcement_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_announcement_banner.jpg&amp;#34&#34;&gt;https://example.com/test_repo_announcement_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_repository_announcement_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        repository_announcement!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            project_name,&lt;br/&gt;            description,&lt;br/&gt;            clone_url,&lt;br/&gt;            &amp;#34;../Cargo.toml&amp;#34;, // Pass the string literal directly, correcting path for include_bytes!&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;            );&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_patch_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-patch&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;fedcba9876543210fedcba9876543210fedcba&amp;#34;;&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_patch_picture.jpg&amp;#34&#34;&gt;https://example.com/test_patch_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_patch_banner.jpg&amp;#34&#34;&gt;https://example.com/test_patch_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_patch_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;        publish_patch!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            &amp;#34;lib.rs&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_pull_request_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-pr&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;        let clone_url = &amp;#34;git@example.com:test/pr-branch.git&amp;#34;;&lt;br/&gt;        let title = Some(&amp;#34;Feat: Implement NIP-34 PR&amp;#34;);&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_picture.jpg&amp;#34&#34;&gt;https://example.com/test_pr_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_banner.jpg&amp;#34&#34;&gt;https://example.com/test_pr_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_pull_request_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        // Test with a title&lt;br/&gt;        publish_pull_request!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            clone_url,&lt;br/&gt;            Some(title.unwrap()),&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;            );&lt;br/&gt;        // Test without a title&lt;br/&gt;        publish_pull_request!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            clone_url&lt;br/&gt;        );&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_pr_update_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::{Keys, EventId};&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-pr-update&amp;#34;;&lt;br/&gt;        let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Placeholder EventId&lt;br/&gt;        let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;        let updated_clone_url = &amp;#34;git@example.com:test/pr-branch-updated.git&amp;#34;;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_update_picture.jpg&amp;#34&#34;&gt;https://example.com/test_pr_update_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_update_banner.jpg&amp;#34&#34;&gt;https://example.com/test_pr_update_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_pr_update_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        publish_pr_update!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            &amp;amp;pr_event_id, // Pass a reference to pr_event_id&lt;br/&gt;            updated_commit_id,&lt;br/&gt;            updated_clone_url,&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_repository_state_event() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-state&amp;#34;;&lt;br/&gt;        let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;abcde12345abcde12345abcde12345abcde12345&amp;#34;;&lt;br/&gt;        use nostr_sdk::EventId;&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;        let _dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_state_picture.jpg&amp;#34&#34;&gt;https://example.com/test_repo_state_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_state_banner.jpg&amp;#34&#34;&gt;https://example.com/test_repo_state_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_repository_state_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        publish_repository_state!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            branch_name,&lt;br/&gt;            commit_id&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    // Test for get_file_hash! macro&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_file_hash_tr() {&lt;br/&gt;        let dir = tempfile::tempdir().unwrap();&lt;br/&gt;        let file_path = dir.path().join(&amp;#34;test_file.txt&amp;#34;);&lt;br/&gt;        let content = &amp;#34;Hello, world!&amp;#34;;&lt;br/&gt;        File::create(&amp;amp;file_path).unwrap().write_all(content.as_bytes()).unwrap();&lt;br/&gt;&lt;br/&gt;        // The macro expects a string literal, so we need to construct the path at compile time.&lt;br/&gt;        // This is a limitation for testing, normally you&amp;#39;d use it with a known file.&lt;br/&gt;        // For testing, we&amp;#39;ll manually verify a file known to be in the project.&lt;br/&gt;        // Let&amp;#39;s test `lib.rs` itself for a more realistic scenario.&lt;br/&gt;        let macro_hash = get_file_hash!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // We will assert on a known file within the crate.&lt;br/&gt;        let bytes = include_bytes!(&amp;#34;lib.rs&amp;#34;);&lt;br/&gt;        let mut hasher_manual = Sha256::new();&lt;br/&gt;        hasher_manual.update(bytes);&lt;br/&gt;        let expected_hash_lib_rs = hasher_manual.finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;&lt;br/&gt;        assert_eq!(macro_hash, expected_hash_lib_rs);&lt;br/&gt;&lt;br/&gt;        // Test with another known file, e.g., Cargo.toml of the core crate&lt;br/&gt;        let cargo_toml_hash = get_file_hash!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;        let cargo_toml_bytes = include_bytes!(&amp;#34;../Cargo.toml&amp;#34;);&lt;br/&gt;        let mut cargo_toml_hasher = Sha256::new();&lt;br/&gt;        cargo_toml_hasher.update(cargo_toml_bytes);&lt;br/&gt;        let expected_cargo_toml_hash = cargo_toml_hasher.finalize()&lt;br/&gt;            .iter()&lt;br/&gt;            .map(|b| format!(&amp;#34;{:02x}&amp;#34;, b))&lt;br/&gt;            .collect::&amp;lt;String&amp;gt;();&lt;br/&gt;        assert_eq!(cargo_toml_hash, expected_cargo_toml_hash);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_get_git_tracked_files_tr() {&lt;br/&gt;        let dir = tempfile::tempdir().unwrap();&lt;br/&gt;        let repo_path = dir.path();&lt;br/&gt;&lt;br/&gt;        // Initialize a git repository&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;init&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to initialize git repo&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // Create some files&lt;br/&gt;        let file1_path = repo_path.join(&amp;#34;file1.txt&amp;#34;);&lt;br/&gt;        File::create(&amp;amp;file1_path).unwrap().write_all(b&amp;#34;content1&amp;#34;).unwrap();&lt;br/&gt;        let file2_path = repo_path.join(&amp;#34;file2.txt&amp;#34;);&lt;br/&gt;        File::create(&amp;amp;file2_path).unwrap().write_all(b&amp;#34;content2&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        // Add and commit files&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;add&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;.&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to git add files&amp;#34;);&lt;br/&gt;        let _ = Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;commit&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;-m&amp;#34;)&lt;br/&gt;            .arg(&amp;#34;Initial commit&amp;#34;)&lt;br/&gt;            .current_dir(repo_path)&lt;br/&gt;            .stdout(std::process::Stdio::null())&lt;br/&gt;            .stderr(std::process::Stdio::null())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to git commit&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let tracked_files = get_git_tracked_files(&amp;amp;repo_path.to_path_buf());&lt;br/&gt;        assert_eq!(tracked_files.len(), 2);&lt;br/&gt;        assert!(tracked_files.contains(&amp;amp;&amp;#34;file1.txt&amp;#34;.to_string()));&lt;br/&gt;        assert!(tracked_files.contains(&amp;amp;&amp;#34;file2.txt&amp;#34;.to_string()));&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    // #[test]&lt;br/&gt;    // fn test_file_hash_as_nostr_private_key() {&lt;br/&gt;    //     use super::file_hash_as_nostr_private_key;&lt;br/&gt;    //     // use std::fs::{File, remove_file};&lt;br/&gt;    //     // use std::io::Write;&lt;br/&gt;    //     // use tempfile::tempdir; // Not needed as we&amp;#39;re using a literal path&lt;br/&gt;    //     use nostr_sdk::prelude::ToBech32;&lt;br/&gt;&lt;br/&gt;    //     let file_path = PathBuf::from(&amp;#34;test_nostr_file_for_macro.txt&amp;#34;);&lt;br/&gt;    //     let content = &amp;#34;Nostr test content!&amp;#34;;&lt;br/&gt;    //     File::create(&amp;amp;file_path).unwrap().write_all(content.as_bytes()).unwrap();&lt;br/&gt;&lt;br/&gt;    //     let keys = file_hash_as_nostr_private_key!(&amp;#34;test_nostr_file_for_macro.txt&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //     assert!(!keys.public_key().to_bech32().unwrap().is_empty());&lt;br/&gt;&lt;br/&gt;    //     remove_file(&amp;amp;file_path).unwrap();&lt;br/&gt;    // }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_metadata_event() {&lt;br/&gt;        use super::publish_metadata_event;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let picture_url = super::DEFAULT_PICTURE_URL;&lt;br/&gt;        let banner_url = super::DEFAULT_BANNER_URL;&lt;br/&gt;        let file_path_str = &amp;#34;test_file.txt&amp;#34;;&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the function doesn&amp;#39;t panic&lt;br/&gt;        // and goes through its execution path.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        let relay_urls = super::get_relay_urls();&lt;br/&gt;        publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            picture_url,&lt;br/&gt;            banner_url,&lt;br/&gt;            file_path_str,&lt;br/&gt;        ).await;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    #[serial]&lt;br/&gt;    async fn test_repository_announcement_event() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::{Keys, EventId};&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let project_name = &amp;#34;test-nip34-repo&amp;#34;;&lt;br/&gt;        let description = &amp;#34;A test repository for NIP-34 announcements.&amp;#34;;&lt;br/&gt;        let clone_url = &amp;#34;git@example.com:test/test-nip34-repo.git&amp;#34;;&lt;br/&gt;        let _dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;        let _file_for_euc = &amp;#34;Cargo.toml&amp;#34;; // Use a known file in your project, as required by include_bytes!&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_announcement_picture.jpg&amp;#34&#34;&gt;https://example.com/test_repo_announcement_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_announcement_banner.jpg&amp;#34&#34;&gt;https://example.com/test_repo_announcement_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_repository_announcement_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        repository_announcement!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            project_name,&lt;br/&gt;            description,&lt;br/&gt;            clone_url,&lt;br/&gt;            &amp;#34;../Cargo.toml&amp;#34;, // Pass the string literal directly, correcting path for include_bytes!&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;            );&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_patch_event() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-patch&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;fedcba9876543210fedcba9876543210fedcba&amp;#34;;&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_patch_picture.jpg&amp;#34&#34;&gt;https://example.com/test_patch_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_patch_banner.jpg&amp;#34&#34;&gt;https://example.com/test_patch_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_patch_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;        publish_patch!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            &amp;#34;lib.rs&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_pull_request_event() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-pr&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;        let clone_url = &amp;#34;git@example.com:test/pr-branch.git&amp;#34;;&lt;br/&gt;        let title = Some(&amp;#34;Feat: Implement NIP-34 PR&amp;#34;);&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_picture.jpg&amp;#34&#34;&gt;https://example.com/test_pr_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_banner.jpg&amp;#34&#34;&gt;https://example.com/test_pr_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_pull_request_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        // Test with a title&lt;br/&gt;        publish_pull_request!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            clone_url,&lt;br/&gt;            Some(title.unwrap()),&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;            );&lt;br/&gt;        // Test without a title&lt;br/&gt;        publish_pull_request!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            commit_id,&lt;br/&gt;            clone_url&lt;br/&gt;        );&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_pr_update_event() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::{Keys, EventId};&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-pr-update&amp;#34;;&lt;br/&gt;        let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Placeholder EventId&lt;br/&gt;        let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;        let updated_clone_url = &amp;#34;git@example.com:test/pr-branch-updated.git&amp;#34;;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_update_picture.jpg&amp;#34&#34;&gt;https://example.com/test_pr_update_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_pr_update_banner.jpg&amp;#34&#34;&gt;https://example.com/test_pr_update_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_pr_update_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        publish_pr_update!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            &amp;amp;pr_event_id, // Pass a reference to pr_event_id&lt;br/&gt;            updated_commit_id,&lt;br/&gt;            updated_clone_url,&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    #[serial]&lt;br/&gt;    async fn test_publish_repository_state_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;        use nostr_sdk::secp256k1::SecretKey as NostrSecretKey;&lt;br/&gt;        &lt;br/&gt;        // 1. Generate FROST keys (1-of-1 for this test to derive a single Nostr key)&lt;br/&gt;        let (shares, _pubkey_package) = super::generate_frost_keys(2, 2).unwrap();&lt;br/&gt;        let signer_id = frost::Identifier::try_from(1 as u16).unwrap();&lt;br/&gt;        let secret_share = shares.get(&amp;amp;signer_id).unwrap();&lt;br/&gt;&lt;br/&gt;        // Convert FROST secret share&amp;#39;s scalar to a Nostr SecretKey&lt;br/&gt;        let frost_secp_secret_key = secret_share.signing_share().to_scalar();&lt;br/&gt;        let nostr_secret_key = NostrSecretKey::from_slice(&amp;amp;frost_secp_secret_key.to_bytes()).unwrap();&lt;br/&gt;        let keys = Keys::new(nostr_secret_key.into());&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-state&amp;#34;;&lt;br/&gt;        let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;        let commit_id = &amp;#34;abcde12345abcde12345abcde12345abcde12345&amp;#34;;&lt;br/&gt;        use nostr_sdk::EventId;&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;        let _dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_state_picture.jpg&amp;#34&#34;&gt;https://example.com/test_repo_state_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_repo_state_banner.jpg&amp;#34&#34;&gt;https://example.com/test_repo_state_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_repository_state_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        publish_repository_state!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            branch_name,&lt;br/&gt;            commit_id&lt;br/&gt;        );    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[tokio::test]&lt;br/&gt;    async fn test_publish_issue_event_tr() {&lt;br/&gt;        use super::get_relay_urls;&lt;br/&gt;        use nostr_sdk::Keys;&lt;br/&gt;        use nostr_sdk::EventId;&lt;br/&gt;        use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;        let keys = Keys::parse(super::DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr Keys from DEFAULT_GNOSTR_KEY&amp;#34;);&lt;br/&gt;        let relay_urls = get_relay_urls();&lt;br/&gt;        let d_tag = &amp;#34;test-repo-for-issue&amp;#34;;&lt;br/&gt;        let issue_id = &amp;#34;456&amp;#34;;&lt;br/&gt;        let title = &amp;#34;Feature: Implement NIP-34 Issues&amp;#34;;&lt;br/&gt;        let content = &amp;#34;This is a test issue to verify the NIP-34 issue macro implementation.&amp;#34;;&lt;br/&gt;        let dummy_build_manifest_id = EventId::from_str(super::DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;        // This test primarily checks that the macro and function compile and execute without panicking.&lt;br/&gt;        // Actual publishing success depends on external network conditions.&lt;br/&gt;        super::publish_metadata_event(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_issue_picture.jpg&amp;#34&#34;&gt;https://example.com/test_issue_picture.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;&lt;a href=&#34;https://example.com/test_issue_banner.jpg&amp;#34&#34;&gt;https://example.com/test_issue_banner.jpg&amp;#34&lt;/a&gt;;,&lt;br/&gt;            &amp;#34;test_publish_issue_event_metadata&amp;#34;,&lt;br/&gt;        ).await;&lt;br/&gt;&lt;br/&gt;        publish_issue!(&lt;br/&gt;            &amp;amp;keys,&lt;br/&gt;            &amp;amp;relay_urls,&lt;br/&gt;            d_tag,&lt;br/&gt;            issue_id,&lt;br/&gt;            title,&lt;br/&gt;            content,&lt;br/&gt;            Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;        );&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;    #[test]&lt;br/&gt;    fn test_frost_signature_flow_tr() {&lt;br/&gt;        let max_signers = 3;&lt;br/&gt;        let min_signers = 2;&lt;br/&gt;        let message = b&amp;#34;This is a test message for FROST signing&amp;#34;;&lt;br/&gt;&lt;br/&gt;        // 1. Key Generation&lt;br/&gt;        let (shares, pubkey_package) = super::generate_frost_keys(max_signers, min_signers).unwrap();&lt;br/&gt;&lt;br/&gt;        let mut commitments = BTreeMap::new();&lt;br/&gt;        let mut nonces_map = BTreeMap::new();&lt;br/&gt;        let mut signature_shares_map = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;        // 2. Commitment Phase (simulated for two signers)&lt;br/&gt;        let signer1_id = frost::Identifier::try_from(1 as u16).unwrap();&lt;br/&gt;        let (nonces1, comms1) = super::create_frost_commitment(&amp;amp;shares[&amp;amp;signer1_id]);&lt;br/&gt;        commitments.insert(signer1_id, comms1);&lt;br/&gt;        nonces_map.insert(signer1_id, nonces1);&lt;br/&gt;&lt;br/&gt;        let signer2_id = frost::Identifier::try_from(2 as u16).unwrap();&lt;br/&gt;        let (nonces2, comms2) = super::create_frost_commitment(&amp;amp;shares[&amp;amp;signer2_id]);&lt;br/&gt;        commitments.insert(signer2_id, comms2);&lt;br/&gt;        nonces_map.insert(signer2_id, nonces2);&lt;br/&gt;&lt;br/&gt;        // 3. Signing Package Creation&lt;br/&gt;        let signing_package = super::create_signing_package(commitments, message);&lt;br/&gt;&lt;br/&gt;        // 4. Signature Share Generation&lt;br/&gt;        let share1 = super::generate_signature_share(&amp;amp;signing_package, &amp;amp;nonces_map[&amp;amp;signer1_id], &amp;amp;shares[&amp;amp;signer1_id]).unwrap();&lt;br/&gt;        signature_shares_map.insert(signer1_id, share1);&lt;br/&gt;&lt;br/&gt;        let share2 = super::generate_signature_share(&amp;amp;signing_package, &amp;amp;nonces_map[&amp;amp;signer2_id], &amp;amp;shares[&amp;amp;signer2_id]).unwrap();&lt;br/&gt;        signature_shares_map.insert(signer2_id, share2);&lt;br/&gt;&lt;br/&gt;        // 5. Aggregation&lt;br/&gt;        let group_signature = super::aggregate_signature_shares(&amp;amp;signing_package, &amp;amp;signature_shares_map, &amp;amp;pubkey_package).unwrap();&lt;br/&gt;&lt;br/&gt;        // 6. Verification&lt;br/&gt;        let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;        super::verify_frost_signature(&amp;amp;group_public_key, message, &amp;amp;group_signature).unwrap();&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:17:37&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs8shjcx26uzuy7mdr84ka607ge8pmsyxw27e8xsa9asylf3m27jeqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5nwkz7n</id>
    
      <title type="html">#![cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs8shjcx26uzuy7mdr84ka607ge8pmsyxw27e8xsa9asylf3m27jeqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5nwkz7n" />
    <content type="html">
      #![cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;use frost::keys::PublicKeyPackage;&lt;br/&gt;use frost::round2::SignatureShare;&lt;br/&gt;use frost::SigningPackage;&lt;br/&gt;use hex;&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;use sha2::Sha256;&lt;br/&gt;use serde_json;&lt;br/&gt;use sha2::Digest;&lt;br/&gt;&lt;br/&gt;pub fn process_relay_share(&lt;br/&gt;    relay_payload_hex: &amp;amp;str,&lt;br/&gt;    signer_id_u16: u16,&lt;br/&gt;    _signing_package: &amp;amp;SigningPackage,&lt;br/&gt;    _pubkey_package: &amp;amp;PublicKeyPackage,&lt;br/&gt;) -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    // In a real scenario, this function would deserialize the share, perform&lt;br/&gt;    // individual verification, and store it for aggregation.&lt;br/&gt;    // For this example, we&amp;#39;ll just acknowledge receipt.&lt;br/&gt;    let _share_bytes = hex::decode(relay_payload_hex)?;&lt;br/&gt;    let _share = SignatureShare::deserialize(&amp;amp;_share_bytes)?;&lt;br/&gt;    let _identifier = frost::Identifier::try_from(signer_id_u16)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;✅ Share from Signer {} processed (simplified).&amp;#34;, signer_id_u16);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_coordinator() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD: Anchor Data Proposal v1&amp;#34;;&lt;br/&gt;&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments.clone(), message);&lt;br/&gt;&lt;br/&gt;    let share1 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces1, &amp;amp;key_package1)?;&lt;br/&gt;    let share1_hex = hex::encode(share1.serialize());&lt;br/&gt;&lt;br/&gt;    let share2 = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces2, &amp;amp;key_package2)?;&lt;br/&gt;    let share2_hex = hex::encode(share2.serialize());&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Coordinator listening for Nostr events (simulated)...&amp;#34;);&lt;br/&gt;&lt;br/&gt;    process_relay_share(&amp;amp;share1_hex, 1_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    process_relay_share(&amp;amp;share2_hex, 2_u16, &amp;amp;signing_package, &amp;amp;pubkey_package)?;&lt;br/&gt;    println!(&amp;#34;All required shares processed. Coordinator would now aggregate.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;/// Simulates a Signer producing a FROST signature share and preparing a Nostr event&lt;br/&gt;/// to be sent to a coordinator via a &amp;#34;mailbox&amp;#34; relay.&lt;br/&gt;///&lt;br/&gt;/// In a real ROAST setup, signers would generate their share and post it&lt;br/&gt;/// encrypted (e.g., using NIP-44) to a coordinator&amp;#39;s &amp;#34;mailbox&amp;#34; on a Nostr relay.&lt;br/&gt;/// This function demonstrates the creation of the signature share and the&lt;br/&gt;/// construction of a *simplified* Nostr event JSON.&lt;br/&gt;///&lt;br/&gt;/// # Arguments&lt;br/&gt;///&lt;br/&gt;/// * `_identifier` - The FROST identifier of the signer. (Currently unused in this specific function body).&lt;br/&gt;/// * `signing_package` - The FROST signing package received from the coordinator.&lt;br/&gt;/// * `nonces` - The signer&amp;#39;s nonces generated in Round 1.&lt;br/&gt;/// * `key_package` - The signer&amp;#39;s FROST key package.&lt;br/&gt;/// * `coordinator_pubkey` - The hex-encoded public key of the ROAST coordinator,&lt;br/&gt;///                          used to tag the Nostr event.&lt;br/&gt;///&lt;br/&gt;/// # Returns&lt;br/&gt;///&lt;br/&gt;/// A `Result` containing the JSON string of the Nostr event if successful,&lt;br/&gt;/// or a `Box&amp;lt;dyn std::error::Error&amp;gt;` if an error occurs.&lt;br/&gt;pub fn create_signer_event(&lt;br/&gt;    _identifier: frost::Identifier,&lt;br/&gt;    signing_package: &amp;amp;frost::SigningPackage,&lt;br/&gt;    nonces: &amp;amp;frost::round1::SigningNonces,&lt;br/&gt;    key_package: &amp;amp;frost::keys::KeyPackage,&lt;br/&gt;    coordinator_pubkey: &amp;amp;str, // The Hex pubkey of the ROAST coordinator&lt;br/&gt;) -&amp;gt; Result&amp;lt;String, Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;&lt;br/&gt;    // 1. Generate the partial signature share (Round 2 of FROST)&lt;br/&gt;    // This share is the core cryptographic output from the signer.&lt;br/&gt;    let share = frost::round2::sign(signing_package, nonces, key_package)?;&lt;br/&gt;    let share_bytes = share.serialize();&lt;br/&gt;    let share_hex = hex::encode(share_bytes);&lt;br/&gt;&lt;br/&gt;    // 2. Create a Session ID to tag the event&lt;br/&gt;    // This ID is derived from the signing package hash, allowing the coordinator&lt;br/&gt;    // to correlate shares belonging to the same signing session.&lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(signing_package.serialize()?);&lt;br/&gt;    let session_id = hex::encode(hasher.finalize());&lt;br/&gt;&lt;br/&gt;    // 3. Construct the Nostr Event JSON (Simplified)&lt;br/&gt;    // This JSON represents the event that a signer would post to a relay.&lt;br/&gt;    // In a production ROAST system, the &amp;#39;content&amp;#39; field (the signature share)&lt;br/&gt;    // would be encrypted for the coordinator using NIP-44.&lt;br/&gt;    let event = serde_json::json!({&lt;br/&gt;        &amp;#34;kind&amp;#34;: 4, // Example: Using Kind 4 (Private Message), though custom Kinds could be used for Sovereign Stack.&lt;br/&gt;        &amp;#34;pubkey&amp;#34;: hex::encode(key_package.verifying_key().serialize()?.as_slice()), // Signer&amp;#39;s public key&lt;br/&gt;        &amp;#34;created_at&amp;#34;: 1712050000, // Example timestamp&lt;br/&gt;        &amp;#34;tags&amp;#34;: [&lt;br/&gt;            [&amp;#34;p&amp;#34;, coordinator_pubkey],       // &amp;#39;p&amp;#39; tag: Directs the event to the coordinator.&lt;br/&gt;            [&amp;#34;i&amp;#34;, session_id],               // &amp;#39;i&amp;#39; tag: Provides a session identifier for filtering/requests.&lt;br/&gt;            [&amp;#34;t&amp;#34;, &amp;#34;frost-signature-share&amp;#34;]   // &amp;#39;t&amp;#39; tag: A searchable label for the event type.&lt;br/&gt;        ],&lt;br/&gt;        &amp;#34;content&amp;#34;: share_hex, // The actual signature share (would be encrypted in production).&lt;br/&gt;        &amp;#34;id&amp;#34;: &amp;#34;...&amp;#34;, // Event ID (filled by relay upon publishing)&lt;br/&gt;        &amp;#34;sig&amp;#34;: &amp;#34;...&amp;#34; // Event signature (filled by relay upon publishing)&lt;br/&gt;    });&lt;br/&gt;&lt;br/&gt;    Ok(event.to_string())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;pub fn simulate_frost_mailbox_post_signer() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    use rand::thread_rng;&lt;br/&gt;    use std::collections::BTreeMap;&lt;br/&gt;    use frost_secp256k1_tr as frost;&lt;br/&gt;&lt;br/&gt;    // This example simulates a single signer&amp;#39;s role in a ROAST mailbox post workflow.&lt;br/&gt;    // The general workflow is:&lt;br/&gt;    // 1. Coordinator sends a request for signatures (e.g., on a BIP-64MOD proposal).&lt;br/&gt;    // 2. Signers receive the proposal, perform local verification.&lt;br/&gt;    // 3. Each signer generates their signature share and posts it (encrypted) to a&lt;br/&gt;    //    Nostr relay, targeting the coordinator&amp;#39;s mailbox.&lt;br/&gt;    // 4. The coordinator collects enough shares to aggregate the final signature.&lt;br/&gt;&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    // For this example, we simulate a 2-of-2 threshold for simplicity.&lt;br/&gt;    let (max_signers, min_signers) = (2, 2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 1. Key Generation (Simulated Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // In a real distributed setup, this would be DKG. Here, a &amp;#34;trusted dealer&amp;#34;&lt;br/&gt;    // generates the shares and public key package.&lt;br/&gt;    let (shares, _pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // For a 2-of-2 scheme, we have two signers. Let&amp;#39;s pick signer 1.&lt;br/&gt;    let signer1_id = frost::Identifier::try_from(1 as u16)?;&lt;br/&gt;    let key_package1: frost::keys::KeyPackage = shares[&amp;amp;signer1_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    let signer2_id = frost::Identifier::try_from(2 as u16)?;&lt;br/&gt;    let key_package2: frost::keys::KeyPackage = shares[&amp;amp;signer2_id].clone().try_into()?;&lt;br/&gt;&lt;br/&gt;    // The message that is to be signed (e.g., a hash of a Git commit or a Nostr event ID).&lt;br/&gt;    let message = b&amp;#34;This is a test message for ROAST mailbox post.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 2. Round 1: Commitment Phase (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Each signer generates nonces and commitments.&lt;br/&gt;    let (nonces1, comms1) = frost::round1::commit(key_package1.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    let (nonces2, comms2) = frost::round1::commit(key_package2.signing_share(), &amp;amp;mut rng);&lt;br/&gt;    &lt;br/&gt;    // The coordinator collects these commitments. Here, we simulate by putting them in a BTreeMap.&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    session_commitments.insert(signer1_id, comms1);&lt;br/&gt;    session_commitments.insert(signer2_id, comms2);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 3. Signing Package Creation (Coordinator&amp;#39;s role, simulated for context)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // The coordinator combines the collected commitments and the message to be signed&lt;br/&gt;    // into a signing package, which is then sent back to the signers.&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, message);&lt;br/&gt;&lt;br/&gt;    // Dummy coordinator public key. In a real scenario, this would be the&lt;br/&gt;    // actual public key of the ROAST coordinator, used for event tagging&lt;br/&gt;    // and encryption (NIP-44).&lt;br/&gt;    let coordinator_pubkey_hex = &amp;#34;0000000000000000000000000000000000000000000000000000000000000001&amp;#34;;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // 4. Create the Signer Event (Signer&amp;#39;s role)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // We demonstrate for signer 1. Signer 2 would perform a similar action.&lt;br/&gt;    let event_json_signer1 = create_signer_event(&lt;br/&gt;        signer1_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces1,&lt;br/&gt;        &amp;amp;key_package1,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 1 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer1);&lt;br/&gt;&lt;br/&gt;    // Similarly, Signer 2 would generate their event:&lt;br/&gt;    let event_json_signer2 = create_signer_event(&lt;br/&gt;        signer2_id,&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;nonces2,&lt;br/&gt;        &amp;amp;key_package2,&lt;br/&gt;        coordinator_pubkey_hex,&lt;br/&gt;    )?;&lt;br/&gt;    println!(&amp;#34;Generated Nostr Event for Signer 2 Mailbox Post:&lt;br/&gt;{}&amp;#34;, event_json_signer2);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}
    </content>
    <updated>2026-04-03T17:17:20&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs92yqwa2yuupxahzga68wy24ujvp5useu4a3g8d7lqsqlf238amsczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5j0nff8</id>
    
      <title type="html">#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))] ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs92yqwa2yuupxahzga68wy24ujvp5useu4a3g8d7lqsqlf238amsczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5j0nff8" />
    <content type="html">
      #[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    use std::fs;&lt;br/&gt;    use std::path::PathBuf;&lt;br/&gt;&lt;br/&gt;    let manifest_dir = PathBuf::from(std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap());&lt;br/&gt;    let crate_src_path = manifest_dir.join(&amp;#34;src&amp;#34;).join(&amp;#34;online_relays_gps.csv&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Only download if the file doesn&amp;#39;t exist or is empty&lt;br/&gt;    if !crate_src_path.exists() || fs::metadata(&amp;amp;crate_src_path).map(|m| m.len() == 0).unwrap_or(true) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Downloading online_relays_gps.csv...&amp;#34;);&lt;br/&gt;        let url = &amp;#34;&lt;a href=&#34;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&#34;&gt;https://raw.githubusercontent.com/permissionlesstech/bitchat/main/relays/online_relays_gps.csv&amp;#34&lt;/a&gt;;;&lt;br/&gt;        match reqwest::get(url).await {&lt;br/&gt;            Ok(response) =&amp;gt; {&lt;br/&gt;                if response.status().is_success() {&lt;br/&gt;                    match response.text().await {&lt;br/&gt;                        Ok(content) =&amp;gt; {&lt;br/&gt;                            fs::write(&amp;amp;crate_src_path, content).expect(&amp;#34;Unable to write online_relays_gps.csv&amp;#34;);&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Successfully downloaded online_relays_gps.csv to {:?}&amp;#34;, crate_src_path);&lt;br/&gt;                        },&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to get text from response: {}&amp;#34;, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                } else {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to download online_relays_gps.csv: HTTP status {}&amp;#34;, response.status());&lt;br/&gt;                }&lt;br/&gt;            },&lt;br/&gt;            Err(e) =&amp;gt; {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to fetch online_relays_gps.csv: {}&amp;#34;, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;)))]&lt;br/&gt;fn main() {&lt;br/&gt;    // Placeholder for when the nostr feature is not enabled or in debug mode&lt;br/&gt;    println!(&amp;#34;cargo:warning=Skipping online_relays_gps.csv download (nostr feature not enabled or debug mode)&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:17:08&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs2nhmyzk9svzgld6s2weaxnx99t8ppssrslavx8duezql2x5k99sczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jv5erm</id>
    
      <title type="html">[package] name = &amp;#34;get_file_hash_core&amp;#34; version = { ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs2nhmyzk9svzgld6s2weaxnx99t8ppssrslavx8duezql2x5k99sczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jv5erm" />
    <content type="html">
      [package]&lt;br/&gt;name = &amp;#34;get_file_hash_core&amp;#34;&lt;br/&gt;version = { workspace = true }&lt;br/&gt;edition = { workspace = true }&lt;br/&gt;description = { workspace = true }&lt;br/&gt;license = { workspace = true }&lt;br/&gt;documentation = { workspace = true }&lt;br/&gt;homepage = { workspace = true }&lt;br/&gt;repository = { workspace = true }&lt;br/&gt;authors = { workspace = true }&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:serde_json&amp;#34;, &amp;#34;dep:sha2&amp;#34;, &amp;#34;dep:hex&amp;#34;, &amp;#34;dep:reqwest&amp;#34;, &amp;#34;dep:tokio&amp;#34;, &amp;#34;dep:csv&amp;#34;, &amp;#34;dep:url&amp;#34;, &amp;#34;dep:frost-secp256k1-tr&amp;#34;, &amp;#34;dep:rand&amp;#34;]&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;sha2 = { workspace = true, optional = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;serde_json = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;csv = { workspace = true, optional = true }&lt;br/&gt;url = { workspace = true, optional = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true, optional = true }&lt;br/&gt;rand = { workspace = true, optional = true }&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;tempfile = { workspace = true }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;] }&lt;br/&gt;csv = { workspace = true }&lt;br/&gt;url = { workspace = true }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;serial_test = { workspace = true, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = { workspace = true }&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;reqwest = { workspace = true, features = [&amp;#34;json&amp;#34;], optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;macros&amp;#34;, &amp;#34;rt-multi-thread&amp;#34;], optional = true }&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:16:48&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsf379pelwravsdrmas7nptkktuspz2xyefjpmzrgfj4f87vdpz49czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5pxnky4</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsf379pelwravsdrmas7nptkktuspz2xyefjpmzrgfj4f87vdpz49czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5pxnky4" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;use get_file_hash::{BUILD_HASH, CARGO_TOML_HASH, LIB_HASH};&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART0: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r&amp;#34;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART3: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART4: &amp;amp;str = r&amp;#34;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART_NIP34: &amp;amp;str = r&amp;#34;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`readme.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;readme.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    let build_message = if BUILD_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let cargo_message = if CARGO_TOML_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;    let lib_message = if LIB_HASH.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}{}&amp;#34;, README_TEMPLATE_PART0, README_TEMPLATE_PART1, README_TEMPLATE_PART_NIP34);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, BUILD_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, build_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART3);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, cargo_message);&lt;br/&gt;    //&lt;br/&gt;    print!(&amp;#34;{}&amp;#34;, README_TEMPLATE_PART4);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** {}&amp;#34;, LIB_HASH);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, lib_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:16:27&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsph0w6dahfxylum5nrcxeqrvja5mqqcujy25xrxppl9v7se3y4dcqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jny4fu</id>
    
      <title type="html">//! A simple command-line tool that calculates and displays the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsph0w6dahfxylum5nrcxeqrvja5mqqcujy25xrxppl9v7se3y4dcqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jny4fu" />
    <content type="html">
      //! A simple command-line tool that calculates and displays the SHA-256 hash of&lt;br/&gt;//! its own source file.&lt;br/&gt;//!&lt;br/&gt;//! This utility demonstrates how to use the `get_file_hash!` macro to obtain&lt;br/&gt;//! the hash of a specified file at compile time and incorporate it into runtime&lt;br/&gt;//! logic.&lt;br/&gt;&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART1: &amp;amp;str = r##&amp;#34;# `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let file_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, file_hash);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;&amp;#34;##;&lt;br/&gt;&lt;br/&gt;const README_TEMPLATE_PART2: &amp;amp;str = r&amp;#34;## Setup and Building&lt;br/&gt;&lt;br/&gt;1.  **Clone the repository:**&lt;br/&gt;    ```bash&lt;br/&gt;    git clone &amp;lt;repository-url&amp;gt;&lt;br/&gt;    cd &amp;lt;repository-name&amp;gt;&lt;br/&gt;    ```&lt;br/&gt;2.  **Build the project:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build&lt;br/&gt;    ```&lt;br/&gt;    During the build, `build.rs` will execute and print the hash of `Cargo.toml`.&lt;br/&gt;3.  **Run the example executable:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo run --bin get_file_hash&lt;br/&gt;    ```&lt;br/&gt;    This will print the hash of `src/bin/get_file_hash.rs` to your console.&lt;br/&gt;&lt;br/&gt;## Updating this `README.md`&lt;br/&gt;&lt;br/&gt;The hash information in this `README.md` is automatically generated by running the example executable.&lt;br/&gt;To update it, execute:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin get_file_hash &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Current File Hash Information (of `src/bin/get_file_hash.rs`)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/get_file_hash.rs`&lt;br/&gt;&amp;#34;;&lt;br/&gt;&lt;br/&gt;/// The main entry point of the application.&lt;br/&gt;///&lt;br/&gt;/// This function calculates the SHA-256 hash of the `get_file_hash.rs` source&lt;br/&gt;/// file using a custom procedural macro and then prints the hash to the&lt;br/&gt;/// console. It also includes a basic integrity verification check.&lt;br/&gt;fn main() {&lt;br/&gt;    // Calculate the SHA-256 hash of the current file (`get_file_hash.rs`) at&lt;br/&gt;    // compile time. The `get_file_hash!` macro reads the file content and&lt;br/&gt;    // computes its hash.&lt;br/&gt;    let self_hash = get_file_hash!(&amp;#34;get_file_hash.rs&amp;#34;);&lt;br/&gt;&lt;br/&gt;    let status_message = if self_hash.starts_with(&amp;#34;e3b0&amp;#34;) {&lt;br/&gt;        &amp;#34;Warning: This hash represents an empty file.&amp;#34;&lt;br/&gt;    } else {&lt;br/&gt;        &amp;#34;Integrity Verified.&amp;#34;&lt;br/&gt;    };&lt;br/&gt;&lt;br/&gt;    print!(&amp;#34;{}{}&amp;#34;, README_TEMPLATE_PART1, README_TEMPLATE_PART2);&lt;br/&gt;    println!(&amp;#34;*   **SHA-256 Hash:** `{}`&amp;#34;, self_hash);&lt;br/&gt;    println!(&amp;#34;*   **Status:** {}.\n&amp;#34;, status_message);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:16:14&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs02cl4k9wpejmr55uem2s34yht73zyjmuh55daalpsyfvq6w6k0fczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f8nxjz</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs02cl4k9wpejmr55uem2s34yht73zyjmuh55daalpsyfvq6w6k0fczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f8nxjz" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let max_signers = 3;&lt;br/&gt;    let min_signers = 2;&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 0: Key Generation (Trusted Dealer)&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    // In a real P2P setup, you&amp;#39;d use Distributed Key Generation (DKG).&lt;br/&gt;    // For local testing/simulations, the trusted dealer is faster.&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verifying the public key exists&lt;br/&gt;    let group_public_key = pubkey_package.verifying_key();&lt;br/&gt;    println!(&amp;#34;Group Public Key: {:?}&amp;#34;, group_public_key);&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 1: Commitment&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Consensus Proposal&amp;#34;;&lt;br/&gt;    let mut signing_commitments = BTreeMap::new();&lt;br/&gt;    let mut participant_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Participants 1 and 2 decide to sign&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        &lt;br/&gt;        // Generate nonces and commitments&lt;br/&gt;        let (nonces, commitments) = frost::round1::commit(&lt;br/&gt;            shares[&amp;amp;identifier].signing_share(),&lt;br/&gt;            &amp;amp;mut rng,&lt;br/&gt;        );&lt;br/&gt;        &lt;br/&gt;        signing_commitments.insert(identifier, commitments);&lt;br/&gt;        participant_nonces.insert(identifier, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Round 2: Signing&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;    let signing_package = frost::SigningPackage::new(signing_commitments, message);&lt;br/&gt;&lt;br/&gt;    for i in 1..=min_signers {&lt;br/&gt;        let identifier = frost::Identifier::try_from(i as u16)?;&lt;br/&gt;        let nonces = &amp;amp;participant_nonces[&amp;amp;identifier];&lt;br/&gt;        &lt;br/&gt;        // Each participant produces a signature share&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;identifier].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(identifier, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    // Finalization: Aggregation&lt;br/&gt;    ////////////////////////////////////////////////////////////////////////////&lt;br/&gt;    &lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // Verification&lt;br/&gt;    group_public_key.verify(message, &amp;amp;group_signature)?;&lt;br/&gt;    &lt;br/&gt;    println!(&amp;#34;Threshold signature verified successfully!&amp;#34;);&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example trusted-dealer --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:15:58&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsfdzqykyzst7uf0zp6vsnmf2rr0y9l6d4redpdyv0e9u3vqcpdyrczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5g8wrmp</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsfdzqykyzst7uf0zp6vsnmf2rr0y9l6d4redpdyv0e9u3vqcpdyrczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5g8wrmp" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;&lt;br/&gt;/// A simplified ROAST Coordinator that manages signing sessions&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;struct RoastCoordinator {&lt;br/&gt;    min_signers: u16,&lt;br/&gt;    _message: Vec&amp;lt;u8&amp;gt;,&lt;br/&gt;    commitments: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningCommitments&amp;gt;,&lt;br/&gt;    nonces: BTreeMap&amp;lt;frost::Identifier, frost::round1::SigningNonces&amp;gt;,&lt;br/&gt;    shares: BTreeMap&amp;lt;frost::Identifier, frost::round2::SignatureShare&amp;gt;,&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;impl RoastCoordinator {&lt;br/&gt;    fn new(min_signers: u16, message: &amp;amp;[u8]) -&amp;gt; Self {&lt;br/&gt;        Self {&lt;br/&gt;            min_signers,&lt;br/&gt;            _message: message.to_vec(),&lt;br/&gt;            commitments: BTreeMap::new(),&lt;br/&gt;            nonces: BTreeMap::new(),&lt;br/&gt;            shares: BTreeMap::new(),&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect commitments until we hit the threshold.&lt;br/&gt;    /// In a real P2P system, this would be an async stream handler.&lt;br/&gt;    fn add_commitment(&amp;amp;mut self, id: frost::Identifier, comms: frost::round1::SigningCommitments, nonces: frost::round1::SigningNonces) {&lt;br/&gt;        if self.commitments.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.commitments.insert(id, comms);&lt;br/&gt;            self.nonces.insert(id, nonces);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    /// ROAST Logic: Collect signature shares.&lt;br/&gt;    fn add_share(&amp;amp;mut self, id: frost::Identifier, share: frost::round2::SignatureShare) {&lt;br/&gt;        if self.shares.len() &amp;lt; self.min_signers as usize {&lt;br/&gt;            self.shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_sign(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.commitments.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    fn is_ready_to_aggregate(&amp;amp;self) -&amp;gt; bool {&lt;br/&gt;        self.shares.len() &amp;gt;= self.min_signers as usize&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (5, 3);&lt;br/&gt;    let message = b&amp;#34;BIP-64MOD Context: ROAST Coordination&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // 1. Setup: Generate keys (Dealer mode for simulation)&lt;br/&gt;    let (key_shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    let mut coordinator = RoastCoordinator::new(min_signers, message);&lt;br/&gt;&lt;br/&gt;    // 2. Round 1: Asynchronous Commitment Collection&lt;br/&gt;    // Simulate signers 1, 3, and 5 responding first (ROAST skips 2 and 4)&lt;br/&gt;    for &amp;amp;id_num in &amp;amp;[1, 3, 5] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_num as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(key_shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        &lt;br/&gt;        // Signers store their nonces locally, send comms to coordinator&lt;br/&gt;        coordinator.add_commitment(id, comms, nonces);&lt;br/&gt;        &lt;br/&gt;        // Note: Signer 2 was &amp;#34;offline&amp;#34;, but ROAST doesn&amp;#39;t care because we hit 3/5.&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 3. Round 2: Signing&lt;br/&gt;    if coordinator.is_ready_to_sign() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        &lt;br/&gt;        let mut temp_shares = BTreeMap::new();&lt;br/&gt;        for &amp;amp;id in coordinator.commitments.keys() {&lt;br/&gt;            // In reality, coordinator sends signing_package to signers&lt;br/&gt;            // Here we simulate the signers producing shares&lt;br/&gt;&lt;br/&gt;            let nonces = &amp;amp;coordinator.nonces[&amp;amp;id];&lt;br/&gt;            &lt;br/&gt;            let key_package: frost::keys::KeyPackage = key_shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;            let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;            temp_shares.insert(id, share);&lt;br/&gt;        }&lt;br/&gt;        for (id, share) in temp_shares {&lt;br/&gt;            coordinator.add_share(id, share);&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 4. Finalization: Aggregation&lt;br/&gt;    if coordinator.is_ready_to_aggregate() {&lt;br/&gt;        let signing_package = frost::SigningPackage::new(coordinator.commitments.clone(), message);&lt;br/&gt;        let group_signature = frost::aggregate(&lt;br/&gt;            &amp;amp;signing_package,&lt;br/&gt;            &amp;amp;coordinator.shares,&lt;br/&gt;            &amp;amp;pubkey_package,&lt;br/&gt;        )?;&lt;br/&gt;&lt;br/&gt;        pubkey_package.verifying_key().verify(message, &amp;amp;group_signature)?;&lt;br/&gt;        println!(&amp;#34;ROAST-coordinated signature verified!&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example roast-experiment --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:15:44&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsv9x7kus4a9qh0uak6ck8vnkp6czk76ng55fneyy7k025ldma4h2czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52v367w</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsv9x7kus4a9qh0uak6ck8vnkp6czk76ng55fneyy7k025ldma4h2czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn52v367w" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;#[allow(unused_imports)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::repository_announcement;&lt;br/&gt;    use get_file_hash_core::get_file_hash;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use sha2::{Digest, Sha256};&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let project_name = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let description = &amp;#34;A fantastic new project example.&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-awesome-repo-example.git&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use a known file in your project&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing repository announcement with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    repository_announcement!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        project_name,&lt;br/&gt;        description,&lt;br/&gt;        clone_url,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use a known file in your project&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository announcement with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example repository_announcement --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:15:31&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsd4mkwr63ff0mj3syc637ffcrcs7v7w6ltcpe0slfrf7h9pelyzhgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5t6ql2d</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsd4mkwr63ff0mj3syc637ffcrcs7v7w6ltcpe0slfrf7h9pelyzhgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5t6ql2d" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_repository_state;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let branch_name = &amp;#34;main&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Publishing repository state...&amp;#34;);&lt;br/&gt;    publish_repository_state!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        branch_name,&lt;br/&gt;        commit_id&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Repository state published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_repository_state --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:15:17&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsduwcr9g2mhd9h3zd8nseel5tss0wch8r69nedvluc9whwnn9d70qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qcle2e</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsduwcr9g2mhd9h3zd8nseel5tss0wch8r69nedvluc9whwnn9d70qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qcle2e" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pull_request;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;0123456789abcdef0123456789abcdef01234567&amp;#34;;&lt;br/&gt;    let clone_url = &amp;#34;git@github.com:user/my-feature-branch.git&amp;#34;;&lt;br/&gt;    let title = Some(&amp;#34;Feat: Add new awesome feature example&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request without title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request without title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With title but without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title but without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title but without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 3: With build_manifest_event_id but without title&lt;br/&gt;    println!(&amp;#34;Publishing pull request with build_manifest_event_id but without title...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        None, // Explicitly pass None for title&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with build_manifest_event_id but without title published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 4: With title and build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing pull request with title and build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pull_request!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        clone_url,&lt;br/&gt;        title,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Pull request with title and build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pull_request --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:15:00&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsxzsfupx8t2dgaytpjw2vvvgypq0ctx9mvxndwtmr9ct7559hhq6czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5cf3hdq</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsxzsfupx8t2dgaytpjw2vvvgypq0ctx9mvxndwtmr9ct7559hhq6czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5cf3hdq" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_pr_update;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let pr_event_id = EventId::from_str(&amp;#34;f6e4d6a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9&amp;#34;).unwrap(); // Example PR Event ID&lt;br/&gt;    let updated_commit_id = &amp;#34;z9y8x7w6v5u4t3s2r1q0p9o8n7m6l5k4j3i2h1g0&amp;#34;;&lt;br/&gt;    let updated_clone_url = &amp;#34;git@github.com:user/my-feature-branch-v2.git&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing PR update with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_pr_update!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        &amp;amp;pr_event_id,&lt;br/&gt;        updated_commit_id,&lt;br/&gt;        updated_clone_url,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;PR update with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_pr_update --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:14:46&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsq8akx0a5t35a9rvqytqlly9h286d2tg6uhsjud06z2hnr7nhj8egzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jtravx</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsq8akx0a5t35a9rvqytqlly9h286d2tg6uhsjud06z2hnr7nhj8egzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5jtravx" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:14:27&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsryn6h6xcezpax597p5akjv3y93wpgcxacr0pf7rjshw852tdss8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn503vqdc</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsryn6h6xcezpax597p5akjv3y93wpgcxacr0pf7rjshw852tdss8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn503vqdc" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_issue;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let issue_id = &amp;#34;123&amp;#34;;&lt;br/&gt;    let title = &amp;#34;Bug: Fix authentication flow example&amp;#34;;&lt;br/&gt;    let content = &amp;#34;The authentication flow is currently broken when users try to log in with invalid credentials. It crashes instead of showing an error message.&amp;#34;;&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id,&lt;br/&gt;        title,&lt;br/&gt;        content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing issue with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_issue!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        issue_id,&lt;br/&gt;        title,&lt;br/&gt;        content,&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Issue with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_issue --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:14:07&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsduklmq99g6t6wsze5fe6qd79vkgdddatcqfcyhqtx0k70pt5yv5czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn55faftu</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsduklmq99g6t6wsze5fe6qd79vkgdddatcqfcyhqtx0k70pt5yv5czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn55faftu" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_post_signer()&lt;br/&gt;}&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox_post --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:13:52&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsry7l9kqeyj7gxgctqcr3teeltcp8ldtv0750quawurzsl73g88sqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ahw8d2</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] fn main() -&amp;gt; Result&amp;lt;(), ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsry7l9kqeyj7gxgctqcr3teeltcp8ldtv0750quawurzsl73g88sqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5ahw8d2" />
    <content type="html">
      &lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    get_file_hash_core::frost_mailbox_logic::simulate_frost_mailbox_coordinator()&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_mailbox --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:13:36&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs9na0c347sqcpsuk70v2pfkspdrtdtj52hz7s8kcmfp0f3jw5cfggzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn56kdk5z</id>
    
      <title type="html">#[cfg(feature = &amp;#34;nostr&amp;#34;)] use frost_secp256k1_tr as ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs9na0c347sqcpsuk70v2pfkspdrtdtj52hz7s8kcmfp0f3jw5cfggzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn56kdk5z" />
    <content type="html">
      #[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use frost_secp256k1_tr as frost; // MUST use the -tr variant for BIP-340/Nostr&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use rand::thread_rng;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use serde_json::json;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use std::collections::BTreeMap;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;use hex;&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;fn main() -&amp;gt; Result&amp;lt;(), Box&amp;lt;dyn std::error::Error&amp;gt;&amp;gt; {&lt;br/&gt;    let mut rng = thread_rng();&lt;br/&gt;    let (max_signers, min_signers) = (3, 2);&lt;br/&gt;&lt;br/&gt;    // 1. Setup Nostr Event Metadata&lt;br/&gt;    let pubkey_hex = &amp;#34;79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798&amp;#34;; // Example&lt;br/&gt;    let created_at = 1712050000;&lt;br/&gt;    let kind = 1;&lt;br/&gt;    let content = &amp;#34;Hello from ROAST threshold signatures!&amp;#34;;&lt;br/&gt;    &lt;br/&gt;    // 2. Serialize for Nostr ID (per NIP-01)&lt;br/&gt;    let event_json = json!([&lt;br/&gt;        0,&lt;br/&gt;        pubkey_hex,&lt;br/&gt;        created_at,&lt;br/&gt;        kind,&lt;br/&gt;        [],&lt;br/&gt;        content&lt;br/&gt;    ]).to_string();&lt;br/&gt;    &lt;br/&gt;    let mut hasher = Sha256::new();&lt;br/&gt;    hasher.update(event_json.as_bytes());&lt;br/&gt;    let event_id = hasher.finalize(); // This 32-byte hash is our signing message&lt;br/&gt;&lt;br/&gt;    // 3. FROST/ROAST Key Generation&lt;br/&gt;    let (shares, pubkey_package) = frost::keys::generate_with_dealer(&lt;br/&gt;        max_signers,&lt;br/&gt;        min_signers,&lt;br/&gt;        frost::keys::IdentifierList::Default,&lt;br/&gt;        &amp;amp;mut rng,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 4. ROAST Coordination Simulation (Round 1: Commitments)&lt;br/&gt;    // In ROAST, the coordinator keeps a &amp;#34;session&amp;#34; open and collects commitments&lt;br/&gt;    let mut session_commitments = BTreeMap::new();&lt;br/&gt;    let mut signer_nonces = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    // Signers 1 and 3 respond first (Signer 2 is offline/slow)&lt;br/&gt;    for &amp;amp;id_val in &amp;amp;[1, 3] {&lt;br/&gt;        let id = frost::Identifier::try_from(id_val as u16)?;&lt;br/&gt;        let (nonces, comms) = frost::round1::commit(shares[&amp;amp;id].signing_share(), &amp;amp;mut rng);&lt;br/&gt;        session_commitments.insert(id, comms);&lt;br/&gt;        signer_nonces.insert(id, nonces);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 5. Round 2: Signing the Nostr ID&lt;br/&gt;    let signing_package = frost::SigningPackage::new(session_commitments, &amp;amp;event_id);&lt;br/&gt;    let mut signature_shares = BTreeMap::new();&lt;br/&gt;&lt;br/&gt;    for (id, nonces) in signer_nonces {&lt;br/&gt;        let key_package: frost::keys::KeyPackage = shares[&amp;amp;id].clone().try_into()?;&lt;br/&gt;        let share = frost::round2::sign(&amp;amp;signing_package, &amp;amp;nonces, &amp;amp;key_package)?;&lt;br/&gt;        signature_shares.insert(id, share);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    // 6. Aggregate into a BIP-340 Signature&lt;br/&gt;    let group_signature = frost::aggregate(&lt;br/&gt;        &amp;amp;signing_package,&lt;br/&gt;        &amp;amp;signature_shares,&lt;br/&gt;        &amp;amp;pubkey_package,&lt;br/&gt;    )?;&lt;br/&gt;&lt;br/&gt;    // 7. Verification (using BIP-340 logic)&lt;br/&gt;    pubkey_package.verifying_key().verify(&amp;amp;event_id, &amp;amp;group_signature)?;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;Nostr Event ID: {}&amp;#34;, hex::encode(event_id));&lt;br/&gt;    println!(&amp;#34;Threshold Signature (BIP-340): {}&amp;#34;, hex::encode(group_signature.serialize()?));&lt;br/&gt;    println!(&amp;#34;Successfully signed Nostr event using ROAST/FROST!&amp;#34;);&lt;br/&gt;&lt;br/&gt;    Ok(())&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example frost_bip_340 --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:13:23&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsgx28m04pagn7fmsnnveua4hyhe7v7zkftmxms6jgvyp99y3cvntgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54tggep</id>
    
      <title type="html"># dist plan --output-format=json &amp;gt; plan-dist-manifest.json # ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsgx28m04pagn7fmsnnveua4hyhe7v7zkftmxms6jgvyp99y3cvntgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54tggep" />
    <content type="html">
      # dist plan --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[workspace]&lt;br/&gt;members = [&amp;#34;cargo:.&amp;#34;, &amp;#34;cargo:src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;# Config for &amp;#39;dist&amp;#39;&lt;br/&gt;[dist]&lt;br/&gt;# The preferred dist version to use in CI (Cargo.toml SemVer syntax)&lt;br/&gt;cargo-dist-version = &amp;#34;0.30.3&amp;#34;&lt;br/&gt;# CI backends to support&lt;br/&gt;ci = &amp;#34;github&amp;#34;&lt;br/&gt;# The installers to generate for each app&lt;br/&gt;installers = [&amp;#34;shell&amp;#34;, &amp;#34;powershell&amp;#34;, &amp;#34;homebrew&amp;#34;, &amp;#34;msi&amp;#34;]&lt;br/&gt;# A GitHub repo to push Homebrew formulas to&lt;br/&gt;tap = &amp;#34;gnostr-org/homebrew-gnostr-org&amp;#34;&lt;br/&gt;# Path that installers should place binaries in&lt;br/&gt;install-path = &amp;#34;CARGO_HOME&amp;#34;&lt;br/&gt;# Publish jobs to run in CI&lt;br/&gt;publish-jobs = [&amp;#34;homebrew&amp;#34;]&lt;br/&gt;# Whether to install an updater program&lt;br/&gt;install-updater = true&lt;br/&gt;# Target platforms to build apps for (Rust target-triple syntax)&lt;br/&gt;targets = [&amp;#34;aarch64-apple-darwin&amp;#34;, &amp;#34;aarch64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-apple-darwin&amp;#34;, &amp;#34;x86_64-unknown-linux-gnu&amp;#34;, &amp;#34;x86_64-unknown-linux-musl&amp;#34;, &amp;#34;x86_64-pc-windows-msvc&amp;#34;]&lt;br/&gt;# Skip checking whether the specified configuration files are up to date&lt;br/&gt;allow-dirty = [&amp;#34;ci&amp;#34;]&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:13:03&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs02672hpm362dx3uvqepa08u5444x992ktqnexh7j9g5zdewwglxgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f2tddy</id>
    
      <title type="html">/// deterministic nostr event build example // deterministic ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs02672hpm362dx3uvqepa08u5444x992ktqnexh7j9g5zdewwglxgzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f2tddy" />
    <content type="html">
      /// deterministic nostr event build example&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;use get_file_hash_core::get_file_hash;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use get_file_hash_core::{get_git_tracked_files, DEFAULT_GNOSTR_KEY, DEFAULT_PICTURE_URL, DEFAULT_BANNER_URL};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use nostr_sdk::{EventBuilder, Keys, EventId, Tag, SecretKey, JsonUtil, Kind, Event};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use serde_json::to_string;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::fs;&lt;br/&gt;use std::path::PathBuf;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use ::hex;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;use std::io::Write;&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn should_remove_relay(error_msg: &amp;amp;str) -&amp;gt; bool {&lt;br/&gt;    error_msg.contains(&amp;#34;relay not connected&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;not in web of trust&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;blocked: not authorized&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;timeout&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;blocked: spam not permitted&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;relay experienced an error trying to publish the latest event&amp;#34;) ||&lt;br/&gt;    error_msg.contains(&amp;#34;duplicate: event already broadcast&amp;#34;)&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn write_event_json_to_file(&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    filename: &amp;amp;str,&lt;br/&gt;    event: &amp;amp;Event,&lt;br/&gt;) -&amp;gt; Option&amp;lt;()&amp;gt; {&lt;br/&gt;    let file_path = output_dir.join(filename);&lt;br/&gt;    if let Some(parent) = file_path.parent() {&lt;br/&gt;        if let Err(e) = fs::create_dir_all(parent) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create parent directories for {}: {}&amp;#34;, file_path.display(), e);&lt;br/&gt;            return None;&lt;br/&gt;        }&lt;br/&gt;    }&lt;br/&gt;    if let Err(e) = fs::File::create(&amp;amp;file_path).and_then(|mut file| write!(file, &amp;#34;{}&amp;#34;, event.as_json())) {&lt;br/&gt;        println!(&amp;#34;Failed to write event JSON to file {}: {}&amp;#34;, file_path.display(), e);&lt;br/&gt;        None&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;Successfully wrote event JSON to {}&amp;#34;, file_path.display());&lt;br/&gt;        Some(())&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;async fn publish_nostr_event_if_release(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    hash: String,&lt;br/&gt;    keys: Keys,&lt;br/&gt;    event_builder: EventBuilder,&lt;br/&gt;    relay_urls: &amp;amp;mut Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    file_path_str: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    total_bytes_sent: &amp;amp;mut usize,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;    let public_key = keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr event for {}: {}&amp;#34;, file_path_str, event_output.val);&lt;br/&gt;&lt;br/&gt;            let event_json_size = to_string(&amp;amp;event).map(|s| s.as_bytes().len()).unwrap_or(0);&lt;br/&gt;            // Print successful relays&lt;br/&gt;            for relay_url in event_output.success.iter() {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Successfully published to relay: {} ({} bytes)&amp;#34;, relay_url, event_json_size);&lt;br/&gt;                *total_bytes_sent &#43;= event_json_size;&lt;br/&gt;            }&lt;br/&gt;            // Print failed relays and remove &amp;#34;unfriendly&amp;#34; relays from the list&lt;br/&gt;            for (relay_url, error_msg) in event_output.failed.iter() {&lt;br/&gt;                if should_remove_relay(error_msg) {&lt;br/&gt;                    if let Err(e) = client.remove_relay(relay_url).await {&lt;br/&gt;                        println!(&amp;#34;cargo:warning=Failed to remove relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;                    }&lt;br/&gt;                     // println!(&amp;#34;cargo:warning=Removed relay {}&amp;#34;, relay_url);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let filename = format!(&amp;#34;{}/{}/{}/{}.json&amp;#34;, file_path_str, hash, public_key.clone(), event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr event for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;pub async fn get_repo_announcement_event(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    _keys: &amp;amp;Keys,&lt;br/&gt;    relay_urls: &amp;amp;Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    repo_url: &amp;amp;str,&lt;br/&gt;    repo_name: &amp;amp;str,&lt;br/&gt;    repo_description: &amp;amp;str,&lt;br/&gt;    git_commit_hash: &amp;amp;str,&lt;br/&gt;    git_branch: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    public_key_hex: &amp;amp;str,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;&lt;br/&gt;    let mut tags = vec![&lt;br/&gt;        Tag::parse([&amp;#34;d&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;description&amp;#34;, repo_description].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;web&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;clone&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;r&amp;#34;, git_commit_hash, &amp;#34;euc&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, git_commit_hash].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;branch&amp;#34;, git_branch].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;maintainers&amp;#34;, &amp;#34;gnostr&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        //Tag::parse([&amp;#34;t&amp;#34;, &amp;#34;personal-fork&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;t&amp;#34;, &amp;#34;gnostr&amp;#34;].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;t&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    // Append each relay url&lt;br/&gt;    for relay in relay_urls {&lt;br/&gt;        tags.push(Tag::parse([&amp;#34;relays&amp;#34;, relay].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap());&lt;br/&gt;    }&lt;br/&gt;    let event_builder = EventBuilder::new(Kind::Custom(30617), repo_description).tags(tags);&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {&lt;br/&gt;        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, event_output.val);&lt;br/&gt;            &lt;br/&gt;            let filename = format!(&amp;#34;30617/{}/{}/{}.json&amp;#34;, repo_name, public_key_hex, event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;pub async fn get_repo_patch_event(&lt;br/&gt;    client: &amp;amp;mut nostr_sdk::Client,&lt;br/&gt;    _keys: &amp;amp;Keys,&lt;br/&gt;    _relay_urls: &amp;amp;Vec&amp;lt;String&amp;gt;,&lt;br/&gt;    repo_url: &amp;amp;str,&lt;br/&gt;    repo_name: &amp;amp;str,&lt;br/&gt;    repo_description: &amp;amp;str,&lt;br/&gt;    git_commit_hash: &amp;amp;str,&lt;br/&gt;    git_branch: &amp;amp;str,&lt;br/&gt;    output_dir: &amp;amp;PathBuf,&lt;br/&gt;    public_key_hex: &amp;amp;str,&lt;br/&gt;) -&amp;gt; Option&amp;lt;EventId&amp;gt; {&lt;br/&gt;&lt;br/&gt;    let tags = vec![&lt;br/&gt;        Tag::parse([&amp;#34;r&amp;#34;, repo_url].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;name&amp;#34;, repo_name].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;description&amp;#34;, repo_description].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;commit&amp;#34;, git_commit_hash].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;        Tag::parse([&amp;#34;branch&amp;#34;, git_branch].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;    ];&lt;br/&gt;&lt;br/&gt;    let event_builder = EventBuilder::new(Kind::Custom(1617), repo_description).tags(tags);&lt;br/&gt;    let event = client.sign_event_builder(event_builder).await.unwrap();&lt;br/&gt;&lt;br/&gt;    match client.send_event(&amp;amp;event).await {&lt;br/&gt;        Ok(event_output) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Published Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, event_output.val);&lt;br/&gt;            &lt;br/&gt;            let filename = format!(&amp;#34;30617/{}/{}/{}.json&amp;#34;, repo_name, public_key_hex, event_output.val.to_string());&lt;br/&gt;            write_event_json_to_file(output_dir, &amp;amp;filename, &amp;amp;event);&lt;br/&gt;            Some(event_output.val)&lt;br/&gt;        },&lt;br/&gt;        Err(e) =&amp;gt; {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to publish Nostr Repository Announcement for {}: {}&amp;#34;, repo_name, e);&lt;br/&gt;            None&lt;br/&gt;        },&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[tokio::main]&lt;br/&gt;async fn main() {&lt;br/&gt;    let manifest_dir = std::env::var(&amp;#34;CARGO_MANIFEST_DIR&amp;#34;).unwrap();&lt;br/&gt;    let is_git_repo = std::path::Path::new(&amp;amp;manifest_dir).join(&amp;#34;.git&amp;#34;).exists();&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_NAME={}&amp;#34;, env!(&amp;#34;CARGO_PKG_NAME&amp;#34;));&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_PKG_VERSION={}&amp;#34;, env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;));&lt;br/&gt;&lt;br/&gt;    if is_git_repo {&lt;br/&gt;        let git_commit_hash_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for commit hash&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_commit_hash_str = if git_commit_hash_output.status.success() &amp;amp;&amp;amp; !git_commit_hash_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_commit_hash_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git commit hash command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_commit_hash_output.status, String::from_utf8_lossy(&amp;amp;git_commit_hash_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH={}&amp;#34;, git_commit_hash_str);&lt;br/&gt;&lt;br/&gt;        let git_branch_output = std::process::Command::new(&amp;#34;git&amp;#34;)&lt;br/&gt;            .args(&amp;amp;[&amp;#34;rev-parse&amp;#34;, &amp;#34;--abbrev-ref&amp;#34;, &amp;#34;HEAD&amp;#34;])&lt;br/&gt;            .stdout(std::process::Stdio::piped())&lt;br/&gt;            .stderr(std::process::Stdio::piped())&lt;br/&gt;            .output()&lt;br/&gt;            .expect(&amp;#34;Failed to execute git command for branch name&amp;#34;);&lt;br/&gt;&lt;br/&gt;        let git_branch_str = if git_branch_output.status.success() &amp;amp;&amp;amp; !git_branch_output.stdout.is_empty() {&lt;br/&gt;            String::from_utf8(git_branch_output.stdout).unwrap().trim().to_string()&lt;br/&gt;        } else {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Git branch command failed or returned empty. Status: {:?}, Stderr: {}&amp;#34;, &lt;br/&gt;                     git_branch_output.status, String::from_utf8_lossy(&amp;amp;git_branch_output.stderr));&lt;br/&gt;            String::new()&lt;br/&gt;        };&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH={}&amp;#34;, git_branch_str);&lt;br/&gt;    } else {&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_COMMIT_HASH=&amp;#34;);&lt;br/&gt;        println!(&amp;#34;cargo:rustc-env=GIT_BRANCH=&amp;#34;);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=.git/HEAD&amp;#34;);&lt;br/&gt;&lt;br/&gt;    //#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    //let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;    let cargo_toml_hash = get_file_hash!(&amp;#34;Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=CARGO_TOML_HASH={}&amp;#34;, cargo_toml_hash);&lt;br/&gt;&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=LIB_HASH={}&amp;#34;, lib_hash);&lt;br/&gt;&lt;br/&gt;    let build_hash = get_file_hash!(&amp;#34;build.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rustc-env=BUILD_HASH={}&amp;#34;, build_hash);&lt;br/&gt;&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=Cargo.toml&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;cargo:rerun-if-changed=build.rs&amp;#34;);&lt;br/&gt;    let online_relays_csv_path = PathBuf::from(&amp;amp;manifest_dir).join(&amp;#34;src/get_file_hash_core/src/online_relays_gps.csv&amp;#34;);&lt;br/&gt;    if online_relays_csv_path.exists() {&lt;br/&gt;        println!(&amp;#34;cargo:rerun-if-changed={}&amp;#34;, online_relays_csv_path.to_str().unwrap());&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;#[cfg(all(not(debug_assertions), feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;    if cfg!(not(debug_assertions)) {&lt;br/&gt;        println!(&amp;#34;cargo:warning=Nostr feature enabled: Build may take longer due to network operations (publishing events to relays).&amp;#34;);&lt;br/&gt;&lt;br/&gt;        // This code only runs in release builds&lt;br/&gt;        let package_version = std::env::var(&amp;#34;CARGO_PKG_VERSION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;        let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;        if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        let files_to_publish: Vec&amp;lt;String&amp;gt; = get_git_tracked_files(&amp;amp;PathBuf::from(&amp;amp;manifest_dir));&lt;br/&gt;&lt;br/&gt;        // Initialize client and keys once&lt;br/&gt;        let initial_keys = Keys::new(SecretKey::from_hex(&amp;amp;hex::encode(Sha256::digest(&amp;#34;initial_seed&amp;#34;.as_bytes()))).expect(&amp;#34;Failed to create initial Nostr keys&amp;#34;));&lt;br/&gt;        let mut client = nostr_sdk::Client::new(initial_keys.clone());&lt;br/&gt;        let mut relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;&lt;br/&gt;        // Add relays to the client&lt;br/&gt;        for relay_url in relay_urls.iter() {&lt;br/&gt;            if let Err(e) = client.add_relay(relay_url).await {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to add relay {}: {}&amp;#34;, relay_url, e);&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        client.connect().await;&lt;br/&gt;        println!(&amp;#34;cargo:warning=Added and connected to {} relays.&amp;#34;, relay_urls.len());&lt;br/&gt;&lt;br/&gt;        let mut published_event_ids: Vec&amp;lt;Tag&amp;gt; = Vec::new();&lt;br/&gt;        let mut total_bytes_sent: usize = 0;&lt;br/&gt;&lt;br/&gt;        for file_path_str in &amp;amp;files_to_publish {&lt;br/&gt;            println!(&amp;#34;cargo:warning=Processing file: {}&amp;#34;, file_path_str);&lt;br/&gt;            match fs::read(file_path_str) {&lt;br/&gt;                Ok(bytes) =&amp;gt; {&lt;br/&gt;                    let mut hasher = Sha256::new();&lt;br/&gt;                    hasher.update(&amp;amp;bytes);&lt;br/&gt;                    let result = hasher.finalize();&lt;br/&gt;                    let file_hash_hex = hex::encode(result);&lt;br/&gt;&lt;br/&gt;                    match SecretKey::from_hex(&amp;amp;file_hash_hex.clone()) {&lt;br/&gt;                        Ok(secret_key) =&amp;gt; {&lt;br/&gt;                            let keys = Keys::new(secret_key);&lt;br/&gt;                            let content = String::from_utf8_lossy(&amp;amp;bytes).into_owned();&lt;br/&gt;                            let tags = vec![&lt;br/&gt;                                Tag::parse([&amp;#34;file&amp;#34;, file_path_str].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                                Tag::parse([&amp;#34;version&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                            ];&lt;br/&gt;                            let event_builder = EventBuilder::text_note(content).tags(tags);&lt;br/&gt;&lt;br/&gt;                            if let Some(event_id) = publish_nostr_event_if_release(&amp;amp;mut client, file_hash_hex, keys.clone(), event_builder, &amp;amp;mut relay_urls, file_path_str, &amp;amp;output_dir, &amp;amp;mut total_bytes_sent).await {&lt;br/&gt;                                published_event_ids.push(Tag::event(event_id));&lt;br/&gt;                            }&lt;br/&gt;&lt;br/&gt;                            // Publish metadata event&lt;br/&gt;                            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                                &amp;amp;keys,&lt;br/&gt;                                &amp;amp;relay_urls,&lt;br/&gt;                                DEFAULT_PICTURE_URL,&lt;br/&gt;                                DEFAULT_BANNER_URL,&lt;br/&gt;                                file_path_str,&lt;br/&gt;                            ).await;&lt;br/&gt;                        }&lt;br/&gt;                        Err(e) =&amp;gt; {&lt;br/&gt;                            println!(&amp;#34;cargo:warning=Failed to derive Nostr secret key for {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                        }&lt;br/&gt;                    }&lt;br/&gt;                }&lt;br/&gt;                Err(e) =&amp;gt; {&lt;br/&gt;                    println!(&amp;#34;cargo:warning=Failed to read file {}: {}&amp;#34;, file_path_str, e);&lt;br/&gt;                }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;&lt;br/&gt;        // Create and publish the build_manifest&lt;br/&gt;        if !published_event_ids.is_empty() {&lt;br/&gt;&lt;br/&gt;            //TODO this will be either the default or detected from env vars PRIVATE_KEY&lt;br/&gt;            let keys = Keys::new(SecretKey::from_hex(DEFAULT_GNOSTR_KEY).expect(&amp;#34;Failed to create Nostr keys from DEFAULT_GNOSTR_KEY&amp;#34;));&lt;br/&gt;            let cloned_keys = keys.clone();&lt;br/&gt;            let content = format!(&amp;#34;Build manifest for get_file_hash v{}&amp;#34;, package_version);&lt;br/&gt;            let mut tags = vec![&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;                Tag::parse([&amp;#34;build_manifest&amp;#34;, &amp;amp;package_version].iter().map(ToString::to_string).collect::&amp;lt;Vec&amp;lt;String&amp;gt;&amp;gt;()).unwrap(),&lt;br/&gt;            ];&lt;br/&gt;            tags.extend(published_event_ids);&lt;br/&gt;&lt;br/&gt;            let event_builder = EventBuilder::text_note(content.clone()).tags(tags);&lt;br/&gt;&lt;br/&gt;            if let Some(event_id) = publish_nostr_event_if_release(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                hex::encode(Sha256::digest(content.as_bytes())),&lt;br/&gt;                keys,&lt;br/&gt;                event_builder,&lt;br/&gt;                &amp;amp;mut relay_urls,&lt;br/&gt;                &amp;#34;build_manifest.json&amp;#34;,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;mut total_bytes_sent,&lt;br/&gt;            ).await {&lt;br/&gt;&lt;br/&gt;                let build_manifest_event_id = Some(event_id);&lt;br/&gt;&lt;br/&gt;            // Publish metadata event for the build manifest&lt;br/&gt;            get_file_hash_core::publish_metadata_event(&lt;br/&gt;                &amp;amp;cloned_keys, // Use reference to cloned keys here&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                DEFAULT_PICTURE_URL,&lt;br/&gt;                DEFAULT_BANNER_URL,&lt;br/&gt;                &amp;amp;format!(&amp;#34;build_manifest:{}&amp;#34;, package_version),&lt;br/&gt;            ).await;&lt;br/&gt;            let git_commit_hash = std::env::var(&amp;#34;GIT_COMMIT_HASH&amp;#34;).unwrap_or_default();&lt;br/&gt;            let git_branch = std::env::var(&amp;#34;GIT_BRANCH&amp;#34;).unwrap_or_default();&lt;br/&gt;            let repo_url = std::env::var(&amp;#34;CARGO_PKG_REPOSITORY&amp;#34;).unwrap();&lt;br/&gt;            let repo_name = std::env::var(&amp;#34;CARGO_PKG_NAME&amp;#34;).unwrap();&lt;br/&gt;            let repo_description = std::env::var(&amp;#34;CARGO_PKG_DESCRIPTION&amp;#34;).unwrap();&lt;br/&gt;&lt;br/&gt;            let output_dir = PathBuf::from(format!(&amp;#34;.gnostr/build/{}&amp;#34;, package_version));&lt;br/&gt;            if let Err(e) = fs::create_dir_all(&amp;amp;output_dir) {&lt;br/&gt;                println!(&amp;#34;cargo:warning=Failed to create output directory {}: {}&amp;#34;, output_dir.display(), e);&lt;br/&gt;            }&lt;br/&gt;&lt;br/&gt;            let announcement_keys = Keys::new(SecretKey::from_hex(build_manifest_event_id.unwrap().to_hex().as_str()).expect(&amp;#34;Failed to create Nostr keys from build_manifest_event_id&amp;#34;));&lt;br/&gt;            let announcement_pubkey_hex = announcement_keys.public_key().to_string();&lt;br/&gt;&lt;br/&gt;            // Publish NIP-34 Repository Announcement&lt;br/&gt;            if let Some(_event_id) = get_repo_announcement_event(&lt;br/&gt;                &amp;amp;mut client,&lt;br/&gt;                &amp;amp;announcement_keys,&lt;br/&gt;                &amp;amp;relay_urls,&lt;br/&gt;                &amp;amp;repo_url,&lt;br/&gt;                &amp;amp;repo_name,&lt;br/&gt;                &amp;amp;repo_description,&lt;br/&gt;                &amp;amp;git_commit_hash,&lt;br/&gt;                &amp;amp;git_branch,&lt;br/&gt;                &amp;amp;output_dir,&lt;br/&gt;                &amp;amp;announcement_pubkey_hex&lt;br/&gt;            ).await {&lt;br/&gt;                // Successfully published announcement&lt;br/&gt;            }&lt;br/&gt;            }&lt;br/&gt;        }&lt;br/&gt;        println!(&amp;#34;cargo:warning=Total bytes sent to Nostr relays: {} bytes&amp;#34;, total_bytes_sent);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;// deterministic nostr event build example&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:12:45&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsvl0tmqt2c6rt4q49xmk29j97s6ayf82f9fmjj3l0xkphzypesh9czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54znps9</id>
    
      <title type="html"># `get_file_hash` macro This project provides a Rust procedural ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsvl0tmqt2c6rt4q49xmk29j97s6ayf82f9fmjj3l0xkphzypesh9czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn54znps9" />
    <content type="html">
      # `get_file_hash` macro&lt;br/&gt;&lt;br/&gt;This project provides a Rust procedural macro, `get_file_hash!`, designed to compute the SHA-256 hash of a specified file at compile time. This hash is then embedded directly into your compiled executable. This feature is invaluable for:&lt;br/&gt;&lt;br/&gt;*   **Integrity Verification:** Ensuring the deployed code hasn&amp;#39;t been tampered with.&lt;br/&gt;*   **Versioning:** Embedding a unique identifier linked to the exact source code version.&lt;br/&gt;*   **Cache Busting:** Generating unique names for assets based on their content.&lt;br/&gt;&lt;br/&gt;## Project Structure&lt;br/&gt;&lt;br/&gt;*   `get_file_hash_core`: A foundational crate containing the `get_file_hash!` macro definition.&lt;br/&gt;*   `get_file_hash`: The main library crate that re-exports the macro.&lt;br/&gt;*   `src/bin/get_file_hash.rs`: An example executable demonstrating the macro&amp;#39;s usage by hashing its own source file and updating this `README.md`.&lt;br/&gt;*   `build.rs`: A build script that also utilizes the `get_file_hash!` macro to hash `Cargo.toml` during the build process.&lt;br/&gt;&lt;br/&gt;## Usage of `get_file_hash!` Macro&lt;br/&gt;&lt;br/&gt;To use the `get_file_hash!` macro, ensure you have `get_file_hash` (or `get_file_hash_core` for direct usage) as a dependency in your `Cargo.toml`.&lt;br/&gt;&lt;br/&gt;### Example&lt;br/&gt;&lt;br/&gt;```rust&lt;br/&gt;use get_file_hash::get_file_hash;&lt;br/&gt;use get_file_hash::CARGO_TOML_HASH;&lt;br/&gt;use sha2::{Digest, Sha256};&lt;br/&gt;&lt;br/&gt;fn main() {&lt;br/&gt;    // The macro resolves the path relative to CARGO_MANIFEST_DIR&lt;br/&gt;    let readme_hash = get_file_hash!(&amp;#34;src/bin/readme.rs&amp;#34;);&lt;br/&gt;    let lib_hash = get_file_hash!(&amp;#34;src/lib.rs&amp;#34;);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/lib.rs is: {}&amp;#34;, lib_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of src/bin/readme.rs is: {}&amp;#34;, readme_hash);&lt;br/&gt;    println!(&amp;#34;The SHA-256 hash of Cargo.toml is: {}&amp;#34;, CARGO_TOML_HASH);&lt;br/&gt;}&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## Release&lt;br/&gt;## [`README.md`](./README.md)&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --bin readme &amp;gt; README.md&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;## [`src/bin/readme.rs`](src/bin/readme.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/bin/readme.rs`&lt;br/&gt;## NIP-34 Integration: Git Repository Events on Nostr&lt;br/&gt;&lt;br/&gt;This library provides a set of powerful macros and functions for integrating Git repository events with the Nostr protocol, adhering to the [NIP-34: Git Repositories on Nostr](&lt;a href=&#34;https://github.com/nostr-protocol/nips/blob/master/34.md&#34;&gt;https://github.com/nostr-protocol/nips/blob/master/34.md&lt;/a&gt;) specification.&lt;br/&gt;&lt;br/&gt;These tools allow you to publish various Git-related events to Nostr relays, enabling decentralized tracking and collaboration for your code repositories.&lt;br/&gt;&lt;br/&gt;### Available NIP-34 Macros&lt;br/&gt;&lt;br/&gt;Each macro provides a convenient way to publish specific NIP-34 event kinds:&lt;br/&gt;&lt;br/&gt;*   [`repository_announcement!`](#repository_announcement)&lt;br/&gt;    *   Publishes a `Repository Announcement` event (Kind 30617) to announce a new or updated Git repository.&lt;br/&gt;*   [`publish_patch!`](#publish_patch)&lt;br/&gt;    *   Publishes a `Patch` event (Kind 1617) containing a Git patch (diff) for a specific commit.&lt;br/&gt;*   [`publish_pull_request!`](#publish_pull_request)&lt;br/&gt;    *   Publishes a `Pull Request` event (Kind 1618) to propose changes and facilitate code review.&lt;br/&gt;*   [`publish_pr_update!`](#publish_pr_update)&lt;br/&gt;    *   Publishes a `Pull Request Update` event (Kind 1619) to update an existing pull request.&lt;br/&gt;*   [`publish_repository_state!`](#publish_repository_state)&lt;br/&gt;    *   Publishes a `Repository State` event (Kind 1620) to announce the current state of a branch (e.g., its latest commit).&lt;br/&gt;*   [`publish_issue!`](#publish_issue)&lt;br/&gt;    *   Publishes an `Issue` event (Kind 1621) to report bugs, request features, or track tasks.&lt;br/&gt;&lt;br/&gt;### Running NIP-34 Examples&lt;br/&gt;&lt;br/&gt;To see these macros in action, navigate to the `examples/` directory and run each example individually with the `nostr` feature enabled:&lt;br/&gt;&lt;br/&gt;```bash&lt;br/&gt;cargo run --example repository_announcement --features nostr&lt;br/&gt;cargo run --example publish_patch --features nostr&lt;br/&gt;cargo run --example publish_pull_request --features nostr&lt;br/&gt;cargo run --example publish_pr_update --features nostr&lt;br/&gt;cargo run --example publish_repository_state --features nostr&lt;br/&gt;cargo run --example publish_issue --features nostr&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;*   **SHA-256 Hash:** 6c6325c5a4c14f44cbda6ca53179ab3d6666ce7c916365668c6dd1d79215db59&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`build.rs`](build.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `build.rs`&lt;br/&gt;*   **SHA-256 Hash:** 20c958c8cbb5c77cf5eb3763b6da149b61241d328df52d39b7aa97903305c889&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`Cargo.toml`](Cargo.toml)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `Cargo.toml`&lt;br/&gt;*   **SHA-256 Hash:** e3f392bf23b5fb40902acd313a8c76d1943060b6805ea8615de62f9baf0c6513&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;##&lt;br/&gt;&lt;br/&gt;## [`src/lib.rs`](src/lib.rs)&lt;br/&gt;&lt;br/&gt;*   **Target File:** `src/lib.rs`&lt;br/&gt;*   **SHA-256 Hash:** 591593482a6c9aac8793aa1e488e613f52a4effb1ec3465fd9d6a54537f2b123&lt;br/&gt;*   **Status:** Integrity Verified..&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:12:25&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqst5rxektwcd9kv6zq00zafe96k2fu5yar3kw4wmq9rcuahpxh5z8czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53jhql7</id>
    
      <title type="html">[workspace] members = [&amp;#34;.&amp;#34;, ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqst5rxektwcd9kv6zq00zafe96k2fu5yar3kw4wmq9rcuahpxh5z8czypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn53jhql7" />
    <content type="html">
      [workspace]&lt;br/&gt;members = [&amp;#34;.&amp;#34;, &amp;#34;src/get_file_hash_core&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.package]&lt;br/&gt;version = &amp;#34;0.3.3&amp;#34;&lt;br/&gt;edition = &amp;#34;2024&amp;#34;&lt;br/&gt;license = &amp;#34;MIT&amp;#34;&lt;br/&gt;authors = [&amp;#34;gnostr admin@gnostr.org&amp;#34;]&lt;br/&gt;documentation = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash#readme&amp;#34&lt;/a&gt;;&lt;br/&gt;homepage = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;repository = &amp;#34;&lt;a href=&#34;https://github.com/gnostr-org/get_file_hash&amp;#34&#34;&gt;https://github.com/gnostr-org/get_file_hash&amp;#34&lt;/a&gt;;&lt;br/&gt;description = &amp;#34;A utility crate providing a procedural macro to compute and embed file hashes at compile time.&amp;#34;&lt;br/&gt;&lt;br/&gt;[package]&lt;br/&gt;name = &amp;#34;get_file_hash&amp;#34;&lt;br/&gt;version.workspace = true&lt;br/&gt;edition.workspace = true&lt;br/&gt;description.workspace = true&lt;br/&gt;repository.workspace = true&lt;br/&gt;homepage.workspace = true&lt;br/&gt;authors.workspace = true&lt;br/&gt;license.workspace = true&lt;br/&gt;&lt;br/&gt;[package.metadata.wix]&lt;br/&gt;upgrade-guid = &amp;#34;DED69220-26E3-4406-B564-7F2B58C56F57&amp;#34;&lt;br/&gt;path-guid = &amp;#34;8DB39A25-8B99-4C25-8CF5-4704353C7C6E&amp;#34;&lt;br/&gt;license = false&lt;br/&gt;eula = false&lt;br/&gt;&lt;br/&gt;[features]&lt;br/&gt;nostr = [&amp;#34;dep:nostr&amp;#34;, &amp;#34;dep:nostr-sdk&amp;#34;, &amp;#34;dep:hex&amp;#34;]&lt;br/&gt;&lt;br/&gt;[workspace.dependencies]&lt;br/&gt;get_file_hash_core = { features = [&amp;#34;nostr&amp;#34;], path = &amp;#34;src/get_file_hash_core&amp;#34;, version = &amp;#34;0.3.3&amp;#34; }&lt;br/&gt;sha2 = &amp;#34;0.11.0&amp;#34;&lt;br/&gt;nostr = &amp;#34;0.44.2&amp;#34;&lt;br/&gt;nostr-sdk = &amp;#34;0.44.0&amp;#34;&lt;br/&gt;hex = &amp;#34;0.4.2&amp;#34;&lt;br/&gt;tokio = &amp;#34;1&amp;#34;&lt;br/&gt;serde_json = &amp;#34;1.0&amp;#34;&lt;br/&gt;csv = { version = &amp;#34;1.3.0&amp;#34;, default-features = false }&lt;br/&gt;url = &amp;#34;2.5.0&amp;#34;&lt;br/&gt;reqwest = { version = &amp;#34;0.12.0&amp;#34;, default-features = false }&lt;br/&gt;tempfile = &amp;#34;3.27.0&amp;#34;&lt;br/&gt;rand = &amp;#34;0.8&amp;#34;&lt;br/&gt;frost-secp256k1-tr = &amp;#34;3.0.0-rc.0&amp;#34;&lt;br/&gt;serial_test = { version = &amp;#34;3.4.0&amp;#34;, features = [&amp;#34;test_logging&amp;#34;] }&lt;br/&gt;log = &amp;#34;0.4&amp;#34;&lt;br/&gt;&lt;br/&gt;[dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;]  }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;nostr = { workspace = true, optional = true }&lt;br/&gt;nostr-sdk = { workspace = true, optional = true }&lt;br/&gt;hex = { workspace = true, optional = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;frost-secp256k1-tr = { workspace = true }&lt;br/&gt;rand = { workspace = true }&lt;br/&gt;serde_json.workspace = true&lt;br/&gt;&lt;br/&gt;[build-dependencies]&lt;br/&gt;get_file_hash_core = { workspace = true, features = [&amp;#34;nostr&amp;#34;] }&lt;br/&gt;sha2 = { workspace = true }&lt;br/&gt;serde_json = { workspace = true }&lt;br/&gt;tokio = { workspace = true, features = [&amp;#34;full&amp;#34;] }&lt;br/&gt;nostr = { workspace = true }&lt;br/&gt;nostr-sdk = { workspace = true }&lt;br/&gt;hex = { workspace = true }&lt;br/&gt;&lt;br/&gt;# The profile that &amp;#39;dist&amp;#39; will build with&lt;br/&gt;[profile.dist]&lt;br/&gt;inherits = &amp;#34;release&amp;#34;&lt;br/&gt;lto = &amp;#34;thin&amp;#34;&lt;br/&gt;&lt;br/&gt;[dev-dependencies]&lt;br/&gt;serial_test = { workspace = true }&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:12:08&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs2xf5zh94mk5r56f9hqfcw0yre9l0kjw956mu4sg8v87uuvve7y8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57mw3kw</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs2xf5zh94mk5r56f9hqfcw0yre9l0kjw956mu4sg8v87uuvve7y8qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57mw3kw" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:11:52&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsf7206e6zhhkkynh9a8svvyd76ysrtc63lvm94lqwg8hn5ty2hprqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5d8xs0p</id>
    
      <title>Nostr event nevent1qqsf7206e6zhhkkynh9a8svvyd76ysrtc63lvm94lqwg8hn5ty2hprqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5d8xs0p</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsf7206e6zhhkkynh9a8svvyd76ysrtc63lvm94lqwg8hn5ty2hprqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5d8xs0p" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:11:34&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqswfn62qnrhrewxlf853ltwr3evemhgsh98w3t6wzmkjas4pwq66lczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f0pkwd</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswfn62qnrhrewxlf853ltwr3evemhgsh98w3t6wzmkjas4pwq66lczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5f0pkwd" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:11:18&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqst8pxe3r4arc5d6rp9pscum7ld8mgj3ly0vrt8kr3nlpp25ae2z9szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5q6q60a</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqst8pxe3r4arc5d6rp9pscum7ld8mgj3ly0vrt8kr3nlpp25ae2z9szypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5q6q60a" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:10:57&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsx9kankr76d4eq93xqxc3dnzpdchgj0yr9lmrxx75jxt8u9dgy6gqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qnwq9z</id>
    
      <title>Nostr event nevent1qqsx9kankr76d4eq93xqxc3dnzpdchgj0yr9lmrxx75jxt8u9dgy6gqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qnwq9z</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsx9kankr76d4eq93xqxc3dnzpdchgj0yr9lmrxx75jxt8u9dgy6gqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5qnwq9z" />
    <content type="html">
      plan-dist-manifest.json&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:07:39&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqswu2gzr5s20z2t9n4uk60tllxcw8qcsdvxq5v5yc3ct9jq6w84e6qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5k5eg8n</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswu2gzr5s20z2t9n4uk60tllxcw8qcsdvxq5v5yc3ct9jq6w84e6qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5k5eg8n" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:07:23&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqswm5n3gsc65wqvvnduqx2mfyk3lk3vnvrzznrtjwdkn8kkmnr7fqczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5cu53wk</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswm5n3gsc65wqvvnduqx2mfyk3lk3vnvrzznrtjwdkn8kkmnr7fqczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5cu53wk" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:07:02&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs29guse4npv2j3vmktz2xjffyue0uvtj4y96fxy2pfyn56g865h8gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5hsdes8</id>
    
      <title type="html">name: Rust on: push: branches: [ &amp;#34;*&amp;#34; ] pull_request: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs29guse4npv2j3vmktz2xjffyue0uvtj4y96fxy2pfyn56g865h8gzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5hsdes8" />
    <content type="html">
      name: Rust&lt;br/&gt;&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;  pull_request:&lt;br/&gt;    branches: [ &amp;#34;*&amp;#34; ]&lt;br/&gt;&lt;br/&gt;env:&lt;br/&gt;  CARGO_TERM_COLOR: always&lt;br/&gt;  FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true&lt;br/&gt;  RUST_LOG: info&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  build:&lt;br/&gt;&lt;br/&gt;    runs-on: ${{ matrix.os }}&lt;br/&gt;    strategy:&lt;br/&gt;      matrix:&lt;br/&gt;        os: [ubuntu-latest, macos-15-intel, macos-latest, windows-latest]&lt;br/&gt;        features_args: [&amp;#34;&amp;#34;, &amp;#34;--no-default-features&amp;#34;, &amp;#34;--features nostr&amp;#34;]&lt;br/&gt;&lt;br/&gt;    steps:&lt;br/&gt;    - uses: actions/checkout@v4&lt;br/&gt;    - name: Build ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --verbose ${{ matrix.features_args }}&lt;br/&gt;    - name: Run workspace tests ${{ matrix.features_args }}&lt;br/&gt;      run: |&lt;br/&gt;        cargo test --workspace ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;    - name: Run get_file_hash_core tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash_core ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Run get_file_hash tests ${{ matrix.features_args }}&lt;br/&gt;      shell: bash&lt;br/&gt;      run: |&lt;br/&gt;        if [[ &amp;#34;${{ matrix.features_args }}&amp;#34; == &amp;#34;--features nostr&amp;#34; ]]; then&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1 --nocapture&lt;br/&gt;        else&lt;br/&gt;          cargo test -p get_file_hash ${{ matrix.features_args }} -- --test-threads 1&lt;br/&gt;        fi&lt;br/&gt;    - name: Build Release ${{ matrix.features_args }}&lt;br/&gt;      run: cargo build --workspace --release ${{ matrix.features_args }}&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:06:54&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs2t37w68hwkss2mp5g4a4dn2sumzazh75rqkxh9mw4k3hvfk4dwjqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5xcjtfq</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs2t37w68hwkss2mp5g4a4dn2sumzazh75rqkxh9mw4k3hvfk4dwjqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5xcjtfq" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:06:34&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs8fcpz52al2gupa54r8sh3txwlpufsd5a2zfhhuf4rnq5y83t0gyczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fs8qw2</id>
    
      <title type="html"># This file was autogenerated by dist: ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs8fcpz52al2gupa54r8sh3txwlpufsd5a2zfhhuf4rnq5y83t0gyczypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fs8qw2" />
    <content type="html">
      # This file was autogenerated by dist: &lt;a href=&#34;https://axodotdev.github.io/cargo-dist&#34;&gt;https://axodotdev.github.io/cargo-dist&lt;/a&gt;&lt;br/&gt;#&lt;br/&gt;# Copyright 2022-2024, axodotdev&lt;br/&gt;# SPDX-License-Identifier: MIT or Apache-2.0&lt;br/&gt;#&lt;br/&gt;# CI that:&lt;br/&gt;#&lt;br/&gt;# * checks for a Git Tag that looks like a release&lt;br/&gt;# * builds artifacts with dist (archives, installers, hashes)&lt;br/&gt;# * uploads those artifacts to temporary workflow zip&lt;br/&gt;# * on success, uploads the artifacts to a GitHub Release&lt;br/&gt;#&lt;br/&gt;# Note that the GitHub Release will be created with a generated&lt;br/&gt;# title/body based on your changelogs.&lt;br/&gt;&lt;br/&gt;name: Release&lt;br/&gt;permissions:&lt;br/&gt;  &amp;#34;contents&amp;#34;: &amp;#34;write&amp;#34;&lt;br/&gt;&lt;br/&gt;# This task will run whenever you push a git tag that looks like a version&lt;br/&gt;# like &amp;#34;1.0.0&amp;#34;, &amp;#34;v0.1.0-prerelease.1&amp;#34;, &amp;#34;my-app/0.1.0&amp;#34;, &amp;#34;releases/v1.0.0&amp;#34;, etc.&lt;br/&gt;# Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where&lt;br/&gt;# PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION&lt;br/&gt;# must be a Cargo-style SemVer Version (must have at least major.minor.patch).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME is specified, then the announcement will be for that&lt;br/&gt;# package (erroring out if it doesn&amp;#39;t have the given version or isn&amp;#39;t dist-able).&lt;br/&gt;#&lt;br/&gt;# If PACKAGE_NAME isn&amp;#39;t specified, then the announcement will be for all&lt;br/&gt;# (dist-able) packages in the workspace with that version (this mode is&lt;br/&gt;# intended for workspaces with only one dist-able package, or with all dist-able&lt;br/&gt;# packages versioned/released in lockstep).&lt;br/&gt;#&lt;br/&gt;# If you push multiple tags at once, separate instances of this workflow will&lt;br/&gt;# spin up, creating an independent announcement for each one. However, GitHub&lt;br/&gt;# will hard limit this to 3 tags per commit, as it will assume more tags is a&lt;br/&gt;# mistake.&lt;br/&gt;#&lt;br/&gt;# If there&amp;#39;s a prerelease-style suffix to the version, then the release(s)&lt;br/&gt;# will be marked as a prerelease.&lt;br/&gt;on:&lt;br/&gt;  push:&lt;br/&gt;    tags:&lt;br/&gt;      - &amp;#34;**[0-9]&#43;.[0-9]&#43;.[0-9]&#43;*&amp;#34;&lt;br/&gt;&lt;br/&gt;jobs:&lt;br/&gt;  # Run &amp;#39;dist plan&amp;#39; (or host) to determine what tasks we need to do&lt;br/&gt;  plan:&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.plan.outputs.manifest }}&lt;br/&gt;      tag: ${{ !github.event.pull_request &amp;amp;&amp;amp; github.ref_name || &amp;#39;&amp;#39; }}&lt;br/&gt;      tag-flag: ${{ !github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;--tag={0}&amp;#39;, github.ref_name) || &amp;#39;&amp;#39; }}&lt;br/&gt;      publishing: ${{ !github.event.pull_request }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install dist&lt;br/&gt;        # we specify bash to get pipefail; it guards against the `curl` command&lt;br/&gt;        # failing. otherwise `sh` won&amp;#39;t catch that `curl` returned non-0&lt;br/&gt;        shell: bash&lt;br/&gt;        run: &amp;#34;curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -LsSf &lt;a href=&#34;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&#34;&gt;https://github.com/axodotdev/cargo-dist/releases/download/v0.30.3/cargo-dist-installer.sh&lt;/a&gt; | sh&amp;#34;&lt;br/&gt;      - name: Cache dist&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/dist&lt;br/&gt;      # sure would be cool if github gave us proper conditionals...&lt;br/&gt;      # so here&amp;#39;s a doubly-nested ternary-via-truthiness to try to provide the best possible&lt;br/&gt;      # functionality based on whether this is a pull_request, and whether it&amp;#39;s from a fork.&lt;br/&gt;      # (PRs run on the *source* but secrets are usually on the *target* -- that&amp;#39;s *good*&lt;br/&gt;      # but also really annoying to build CI around when it needs secrets to work right.)&lt;br/&gt;      - id: plan&lt;br/&gt;        run: |&lt;br/&gt;          dist ${{ (!github.event.pull_request &amp;amp;&amp;amp; format(&amp;#39;host --steps=create --tag={0}&amp;#39;, github.ref_name)) || &amp;#39;plan&amp;#39; }} --output-format=json &amp;gt; plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;          cat plan-dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; plan-dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-plan-dist-manifest&lt;br/&gt;          path: plan-dist-manifest.json&lt;br/&gt;&lt;br/&gt;  # Build and packages all the platform-specific things&lt;br/&gt;  build-local-artifacts:&lt;br/&gt;    name: build-local-artifacts (${{ join(matrix.targets, &amp;#39;, &amp;#39;) }})&lt;br/&gt;    # Let the initial task tell us to not run (currently very blunt)&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;    if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null &amp;amp;&amp;amp; (needs.plan.outputs.publishing == &amp;#39;true&amp;#39; || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == &amp;#39;upload&amp;#39;) }}&lt;br/&gt;    strategy:&lt;br/&gt;      fail-fast: false&lt;br/&gt;      # Target platforms/runners are computed by dist in create-release.&lt;br/&gt;      # Each member of the matrix has the following arguments:&lt;br/&gt;      #&lt;br/&gt;      # - runner: the github runner&lt;br/&gt;      # - dist-args: cli flags to pass to dist&lt;br/&gt;      # - install-dist: expression to run to install dist on the runner&lt;br/&gt;      #&lt;br/&gt;      # Typically there will be:&lt;br/&gt;      # - 1 &amp;#34;global&amp;#34; task that builds universal installers&lt;br/&gt;      # - N &amp;#34;local&amp;#34; tasks that build each platform&amp;#39;s binaries and platform-specific installers&lt;br/&gt;      matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }}&lt;br/&gt;    runs-on: ${{ matrix.runner }}&lt;br/&gt;    container: ${{ matrix.container &amp;amp;&amp;amp; matrix.container.image || null }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, &amp;#39;-&amp;#39;) }}-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - name: enable windows longpaths&lt;br/&gt;        run: |&lt;br/&gt;          git config --global core.longpaths true&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install Rust non-interactively if not already installed&lt;br/&gt;        if: ${{ matrix.container }}&lt;br/&gt;        run: |&lt;br/&gt;          if ! command -v cargo &amp;gt; /dev/null 2&amp;gt;&amp;amp;1; then&lt;br/&gt;            curl --proto &amp;#39;=https&amp;#39; --tlsv1.2 -sSf &lt;a href=&#34;https://sh.rustup.rs&#34;&gt;https://sh.rustup.rs&lt;/a&gt; | sh -s -- -y&lt;br/&gt;            echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;          fi&lt;br/&gt;      - name: Install dist&lt;br/&gt;        run: ${{ matrix.install_dist.run }}&lt;br/&gt;      # Get the dist-manifest&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Install dependencies&lt;br/&gt;        run: |&lt;br/&gt;          ${{ matrix.packages_install }}&lt;br/&gt;      - name: Build artifacts&lt;br/&gt;        run: |&lt;br/&gt;          # Actually do builds and make zips and whatnot&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        name: Post-build&lt;br/&gt;        # We force bash here just because github makes it really hard to get values up&lt;br/&gt;        # to &amp;#34;real&amp;#34; actions without writing to env-vars, and writing to env-vars has&lt;br/&gt;        # inconsistent syntax between shell and powershell.&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          dist print-upload-files-from-manifest --manifest dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-local-${{ join(matrix.targets, &amp;#39;_&amp;#39;) }}&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;&lt;br/&gt;  # Build and package all the platform-agnostic(ish) things&lt;br/&gt;  build-global-artifacts:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Get all the local artifacts for the global tasks to use (for e.g. checksums)&lt;br/&gt;      - name: Fetch local artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: cargo-dist&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json &amp;#34;--artifacts=global&amp;#34; &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;dist ran successfully&amp;#34;&lt;br/&gt;&lt;br/&gt;          # Parse out what we just built and upload it to scratch storage&lt;br/&gt;          echo &amp;#34;paths&amp;lt;&amp;lt;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          jq --raw-output &amp;#34;.upload_files[]&amp;#34; dist-manifest.json &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;          echo &amp;#34;EOF&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;&lt;br/&gt;          cp dist-manifest.json &amp;#34;$BUILD_MANIFEST_NAME&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload artifacts&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: artifacts-build-global&lt;br/&gt;          path: |&lt;br/&gt;            ${{ steps.cargo-dist.outputs.paths }}&lt;br/&gt;            ${{ env.BUILD_MANIFEST_NAME }}&lt;br/&gt;  # Determines if we should publish/announce&lt;br/&gt;  host:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - build-local-artifacts&lt;br/&gt;      - build-global-artifacts&lt;br/&gt;    # Only run if we&amp;#39;re &amp;#34;publishing&amp;#34;, and only if plan, local and global didn&amp;#39;t fail (skipped is fine)&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.plan.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; needs.plan.outputs.publishing == &amp;#39;true&amp;#39; &amp;amp;&amp;amp; (needs.build-global-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-global-artifacts.result == &amp;#39;success&amp;#39;) &amp;amp;&amp;amp; (needs.build-local-artifacts.result == &amp;#39;skipped&amp;#39; || needs.build-local-artifacts.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    outputs:&lt;br/&gt;      val: ${{ steps.host.outputs.manifest }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;      #- name: Install sccache&lt;br/&gt;      #  run: |&lt;br/&gt;      #    cargo install sccache --version 0.4.0 --locked&lt;br/&gt;      #    echo &amp;#34;$HOME/.cargo/bin&amp;#34; &amp;gt;&amp;gt; $GITHUB_PATH&lt;br/&gt;      - name: Install cached dist&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          name: cargo-dist-cache&lt;br/&gt;          path: ~/.cargo/bin/&lt;br/&gt;      - run: chmod &#43;x ~/.cargo/bin/dist&lt;br/&gt;      # Fetch artifacts from scratch-storage&lt;br/&gt;      - name: Fetch artifacts&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: target/distrib/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - id: host&lt;br/&gt;        shell: bash&lt;br/&gt;        run: |&lt;br/&gt;          dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json &amp;gt; dist-manifest.json&lt;br/&gt;          echo &amp;#34;artifacts uploaded and released successfully&amp;#34;&lt;br/&gt;          cat dist-manifest.json&lt;br/&gt;          echo &amp;#34;manifest=$(jq -c &amp;#34;.&amp;#34; dist-manifest.json)&amp;#34; &amp;gt;&amp;gt; &amp;#34;$GITHUB_OUTPUT&amp;#34;&lt;br/&gt;      - name: &amp;#34;Upload dist-manifest.json&amp;#34;&lt;br/&gt;        uses: actions/upload-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          # Overwrite the previous copy&lt;br/&gt;          name: artifacts-dist-manifest&lt;br/&gt;          path: dist-manifest.json&lt;br/&gt;      # Create a GitHub Release while uploading all files to it&lt;br/&gt;      - name: &amp;#34;Download GitHub Artifacts&amp;#34;&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: artifacts&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      - name: Cleanup&lt;br/&gt;        run: |&lt;br/&gt;          # Remove the granular manifests&lt;br/&gt;          rm -f artifacts/*-dist-manifest.json&lt;br/&gt;      - name: Create GitHub Release&lt;br/&gt;        env:&lt;br/&gt;          PRERELEASE_FLAG: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease &amp;amp;&amp;amp; &amp;#39;--prerelease&amp;#39; || &amp;#39;&amp;#39; }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_TITLE: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_title }}&amp;#34;&lt;br/&gt;          ANNOUNCEMENT_BODY: &amp;#34;${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}&amp;#34;&lt;br/&gt;          RELEASE_COMMIT: &amp;#34;${{ github.sha }}&amp;#34;&lt;br/&gt;        run: |&lt;br/&gt;          # Write and read notes from a file to avoid quoting breaking things&lt;br/&gt;          echo &amp;#34;$ANNOUNCEMENT_BODY&amp;#34; &amp;gt; $RUNNER_TEMP/notes.txt&lt;br/&gt;&lt;br/&gt;          gh release create &amp;#34;${{ needs.plan.outputs.tag }}&amp;#34; --target &amp;#34;$RELEASE_COMMIT&amp;#34; $PRERELEASE_FLAG --title &amp;#34;$ANNOUNCEMENT_TITLE&amp;#34; --notes-file &amp;#34;$RUNNER_TEMP/notes.txt&amp;#34; artifacts/*&lt;br/&gt;&lt;br/&gt;  publish-homebrew-formula:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;      PLAN: ${{ needs.plan.outputs.val }}&lt;br/&gt;      GITHUB_USER: &amp;#34;axo bot&amp;#34;&lt;br/&gt;      GITHUB_EMAIL: &amp;#34;admin&#43;bot@axo.dev&amp;#34;&lt;br/&gt;    if: ${{ !fromJson(needs.plan.outputs.val).announcement_is_prerelease || fromJson(needs.plan.outputs.val).publish_prereleases }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: true&lt;br/&gt;          repository: &amp;#34;gnostr-org/homebrew-gnostr&amp;#34;&lt;br/&gt;          token: ${{ secrets.HOMEBREW_TAP_TOKEN }}&lt;br/&gt;      # So we have access to the formula&lt;br/&gt;      - name: Fetch homebrew formulae&lt;br/&gt;        uses: actions/download-artifact@v4&lt;br/&gt;        with:&lt;br/&gt;          pattern: artifacts-*&lt;br/&gt;          path: Formula/&lt;br/&gt;          merge-multiple: true&lt;br/&gt;      # This is extra complex because you can make your Formula name not match your app name&lt;br/&gt;      # so we need to find releases with a *.rb file, and publish with that filename.&lt;br/&gt;      - name: Commit formula files&lt;br/&gt;        run: |&lt;br/&gt;          git config --global user.name &amp;#34;${GITHUB_USER}&amp;#34;&lt;br/&gt;          git config --global user.email &amp;#34;${GITHUB_EMAIL}&amp;#34;&lt;br/&gt;&lt;br/&gt;          for release in $(echo &amp;#34;$PLAN&amp;#34; | jq --compact-output &amp;#39;.releases[] | select([.artifacts[] | endswith(&amp;#34;.rb&amp;#34;)] | any)&amp;#39;); do&lt;br/&gt;            filename=$(echo &amp;#34;$release&amp;#34; | jq &amp;#39;.artifacts[] | select(endswith(&amp;#34;.rb&amp;#34;))&amp;#39; --raw-output)&lt;br/&gt;            name=$(echo &amp;#34;$filename&amp;#34; | sed &amp;#34;s/\.rb$//&amp;#34;)&lt;br/&gt;            version=$(echo &amp;#34;$release&amp;#34; | jq .app_version --raw-output)&lt;br/&gt;&lt;br/&gt;            export PATH=&amp;#34;/home/linuxbrew/.linuxbrew/bin:$PATH&amp;#34;&lt;br/&gt;            brew update&lt;br/&gt;            # We avoid reformatting user-provided data such as the app description and homepage.&lt;br/&gt;            brew style --except-cops FormulaAudit/Homepage,FormulaAudit/Desc,FormulaAuditStrict --fix &amp;#34;Formula/${filename}&amp;#34; || true&lt;br/&gt;&lt;br/&gt;            git add &amp;#34;Formula/${filename}&amp;#34;&lt;br/&gt;            git commit -m &amp;#34;${name} ${version}&amp;#34;&lt;br/&gt;          done&lt;br/&gt;          git push origin HEAD&lt;br/&gt;&lt;br/&gt;  announce:&lt;br/&gt;    needs:&lt;br/&gt;      - plan&lt;br/&gt;      - host&lt;br/&gt;      - publish-homebrew-formula&lt;br/&gt;    # use &amp;#34;always() &amp;amp;&amp;amp; ...&amp;#34; to allow us to wait for all publish jobs while&lt;br/&gt;    # still allowing individual publish jobs to skip themselves (for prereleases).&lt;br/&gt;    # &amp;#34;host&amp;#34; however must run to completion, no skipping allowed!&lt;br/&gt;    if: ${{ always() &amp;amp;&amp;amp; needs.host.result == &amp;#39;success&amp;#39; &amp;amp;&amp;amp; (needs.publish-homebrew-formula.result == &amp;#39;skipped&amp;#39; || needs.publish-homebrew-formula.result == &amp;#39;success&amp;#39;) }}&lt;br/&gt;    runs-on: &amp;#34;ubuntu-22.04&amp;#34;&lt;br/&gt;    env:&lt;br/&gt;      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}&lt;br/&gt;    steps:&lt;br/&gt;      - uses: actions/checkout@v4&lt;br/&gt;        with:&lt;br/&gt;          persist-credentials: false&lt;br/&gt;          submodules: recursive&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:06:06&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs0xwsvn9n7sev928kcm2mm02thexwt3y7rtq9xt4w3gjx6ed0gzzqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5uzdn0j</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs0xwsvn9n7sev928kcm2mm02thexwt3y7rtq9xt4w3gjx6ed0gzzqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5uzdn0j" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T17:00:37&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqstmxsga49fk3rvh4qgd7xpg89a2rluljn9d7f69h9y8jnks5k7hmqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5px7gmg</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqstmxsga49fk3rvh4qgd7xpg89a2rluljn9d7f69h9y8jnks5k7hmqzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5px7gmg" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T16:58:29&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqswztnsx7mvtazh8lhzeyyx9f89veajkuyvnhrd0tth9egcyx6888qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5gxags3</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqswztnsx7mvtazh8lhzeyyx9f89veajkuyvnhrd0tth9egcyx6888qzypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5gxags3" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T16:55:43&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqs87fa4s3sckm4vj689p22gn48e5xxses0rdlp9j2tzk6udmz39heszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5zprk6n</id>
    
      <title type="html"># `build.rs` Documentation This document explains the ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqs87fa4s3sckm4vj689p22gn48e5xxses0rdlp9j2tzk6udmz39heszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5zprk6n" />
    <content type="html">
      # `build.rs` Documentation&lt;br/&gt;&lt;br/&gt;This document explains the functionality of the `build.rs` script in this project. The `build.rs` script is a special Rust file that, if present, Cargo will compile and run *before* compiling the rest of your package. It&amp;#39;s typically used for tasks that need to be performed during the build process, such as generating code, setting environment variables, or performing conditional compilation.&lt;br/&gt;&lt;br/&gt;## Core Functionality&lt;br/&gt;&lt;br/&gt;The `build.rs` script in this project performs the following key functions:&lt;br/&gt;&lt;br/&gt;1.  **Environment Variable Injection:** It computes various project-related values at compile time and injects them as environment variables (`CARGO_RUSTC_ENV=...`) that can be accessed by the main crate using `env!(&amp;#34;VAR_NAME&amp;#34;)`. This includes:&lt;br/&gt;    *   `CARGO_PKG_NAME`: The name of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `CARGO_PKG_VERSION`: The version of the current package (from `Cargo.toml`).&lt;br/&gt;    *   `GIT_COMMIT_HASH`: The full commit hash of the current Git HEAD (if in a Git repository).&lt;br/&gt;    *   `GIT_BRANCH`: The name of the current Git branch (if in a Git repository).&lt;br/&gt;    *   `CARGO_TOML_HASH`: The SHA-256 hash of the `Cargo.toml` file.&lt;br/&gt;    *   `LIB_HASH`: The SHA-256 hash of the `src/lib.rs` file.&lt;br/&gt;    *   `BUILD_HASH`: The SHA-256 hash of the `build.rs` file itself.&lt;br/&gt;&lt;br/&gt;2.  **Rerun Conditions:** It tells Cargo when to re-run the build script. This ensures that the injected environment variables and any conditional compilation logic are up-to-date if relevant files change:&lt;br/&gt;    *   `Cargo.toml`&lt;br/&gt;    *   `src/lib.rs`&lt;br/&gt;    *   `build.rs`&lt;br/&gt;    *   `.git/HEAD` (to detect changes in the Git repository like new commits or branch switches).&lt;br/&gt;    *   `src/get_file_hash_core/src/online_relays_gps.csv` (conditionally, if the file exists).&lt;br/&gt;&lt;br/&gt;3.  **Conditional Nostr Event Publishing (Release Builds with `nostr` feature):**&lt;br/&gt;    If the project is being compiled in **release mode (`--release`)** and the **`nostr` feature is enabled (`--features nostr`)**, the `build.rs` script will connect to Nostr relays and publish events. This is intended for &amp;#34;deterministic Nostr event build examples&amp;#34; as indicated by the comments in the file.&lt;br/&gt;&lt;br/&gt;    *   **Relay Management:** It retrieves a list of default relay URLs. During event publishing, it identifies and removes &amp;#34;unfriendly&amp;#34; or unresponsive relays (e.g., those with timeout, connection issues, or spam blocks) from the list for subsequent publications.&lt;br/&gt;    *   **File Hashing and Key Generation:** For each Git-tracked file (when in a Git repository), it computes its SHA-256 hash. This hash is then used to derive a Nostr `SecretKey`.&lt;br/&gt;    *   **Event Creation:**&lt;br/&gt;        *   **Individual File Events:** For each Git-tracked file, a Nostr `text_note` event is created. This event includes tags for:&lt;br/&gt;            *   `#file`: The path of the file.&lt;br/&gt;            *   `#version`: The package version.&lt;br/&gt;            *   `#commit`: The Git commit hash (if in a Git repository).&lt;br/&gt;            *   `#branch`: The Git branch name (if in a Git repository).&lt;br/&gt;        *   **Metadata Event:** It publishes a metadata event using `get_file_hash_core::publish_metadata_event`.&lt;br/&gt;        *   **Linking Event (Build Manifest):** After processing all individual files, if any events were published, a final &amp;#34;build manifest&amp;#34; `text_note` event is created. This event links to all the individual file events that were published during the build using event tags.&lt;br/&gt;    *   **Output Storage:** The JSON representation of successfully published Nostr events (specifically the `EventId`) is saved to `~/.gnostr/build/{package_version}/{file_path_str_sanitized}/{hash}/{public_key}/{event_id}.json`. This provides a local record of what was published.&lt;br/&gt;&lt;br/&gt;### `publish_nostr_event_if_release` Function&lt;br/&gt;&lt;br/&gt;This asynchronous helper function is responsible for:&lt;br/&gt;*   Adding relays to the Nostr client.&lt;br/&gt;*   Connecting to relays.&lt;br/&gt;*   Signing the provided `EventBuilder` to create an `Event`.&lt;br/&gt;*   Sending the event to the configured relays.&lt;br/&gt;*   Logging success or failure for each relay.&lt;br/&gt;*   Identifying and removing unresponsive relays from the `relay_urls` list.&lt;br/&gt;*   Saving the published event&amp;#39;s JSON to the local filesystem.&lt;br/&gt;&lt;br/&gt;### `should_remove_relay` Function&lt;br/&gt;&lt;br/&gt;This helper function determines if a relay should be considered &amp;#34;unfriendly&amp;#34; or unresponsive based on common error messages received during Nostr event publication.&lt;br/&gt;&lt;br/&gt;## Usage&lt;br/&gt;&lt;br/&gt;To prevent &amp;#39;Too many open files&amp;#39; errors, especially during builds and tests involving numerous file operations or subprocesses (like `git ls-files` or parallel test execution), it may be necessary to increase the file descriptor limit.&lt;br/&gt;&lt;br/&gt;*   **For local development**: Run `ulimit -n 4096` in your terminal session before executing `cargo build` or `cargo test`. This setting is session-specific.&lt;br/&gt;*   **For CI environments**: The `.github/workflows/rust.yml` workflow is configured to set `ulimit -n 4096` for relevant test steps to ensure consistent execution.&lt;br/&gt;&lt;br/&gt;The values set by `build.rs` can be accessed in your Rust code (e.g., `src/lib.rs`) at compile time using the `env!` macro. For example:&lt;br/&gt;```rust&lt;br/&gt;pub const CARGO_PKG_VERSION: &amp;amp;str = env!(&amp;#34;CARGO_PKG_VERSION&amp;#34;);&lt;br/&gt;```&lt;br/&gt;&lt;br/&gt;The Nostr event publishing functionality of `build.rs` is primarily for release builds with the `nostr` feature enabled, allowing for the automatic, deterministic publication of project state to the Nostr network as part of the CI/CD pipeline.&lt;br/&gt;&lt;br/&gt;## Example Commands&lt;br/&gt;&lt;br/&gt;To interact with the `build.rs` script&amp;#39;s features, especially those related to Nostr event publishing, you can use the following `cargo` commands:&lt;br/&gt;&lt;br/&gt;*   **Build in release mode with Nostr feature (verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --workspace --features nostr -vv&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run tests for `get_file_hash_core` sequentially with Nostr feature and verbose logging (as in CI):**&lt;br/&gt;    ```bash&lt;br/&gt;    RUST_LOG=info,nostr_sdk=debug,frost=debug cargo test -p get_file_hash_core --features nostr -- --test-threads 1 --nocapture&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run all workspace tests in release mode with Nostr feature:**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --workspace --release --features nostr&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Build `get_file_hash_core` in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo build --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;*   **Run `get_file_hash_core` tests in release mode with Nostr feature (very verbose output):**&lt;br/&gt;    ```bash&lt;br/&gt;    cargo test --release --features nostr -vv -p get_file_hash_core&lt;br/&gt;    ```&lt;br/&gt;&lt;br/&gt;
    </content>
    <updated>2026-04-03T16:52:19&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsz9935lwf4h8nns5mxkfr6ghqx0f8svwua0maug3d6tp9mj44f6eszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57n42dt</id>
    
      <title type="html">Relay URL,Latitude,Longitude wot.nostr.party,36.1627,-86.7816 ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsz9935lwf4h8nns5mxkfr6ghqx0f8svwua0maug3d6tp9mj44f6eszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn57n42dt" />
    <content type="html">
      Relay URL,Latitude,Longitude&lt;br/&gt;wot.nostr.party,36.1627,-86.7816&lt;br/&gt;nostr.simplex.icu,50.1109,8.68213&lt;br/&gt;relay.snort.social,53.3498,-6.26031&lt;br/&gt;nostr.stakey.net,52.3676,4.90414&lt;br/&gt;relay.mccormick.cx,52.3563,4.95714&lt;br/&gt;nostr.overmind.lol,43.6532,-79.3832&lt;br/&gt;nostriches.club,43.6532,-79.3832&lt;br/&gt;kanagrovv-pyramid.kozow.com,43.4305,-83.9638&lt;br/&gt;relay.toastr.net,40.8054,-74.0241&lt;br/&gt;relay.primal.net,43.6532,-79.3832&lt;br/&gt;r.bitcoinhold.net,43.6532,-79.3832&lt;br/&gt;wot.dtonon.com,43.6532,-79.3832&lt;br/&gt;santo.iguanatech.net,40.8302,-74.1299&lt;br/&gt;relay2.ngengine.org,43.6532,-79.3832&lt;br/&gt;nostr.oxtr.dev,50.4754,12.3683&lt;br/&gt;simplex.icu,50.1109,8.68213&lt;br/&gt;bitchat.nostr1.com,38.6327,-90.1961&lt;br/&gt;relay.nostu.be,40.4167,-3.70329&lt;br/&gt;nostr.mifen.me,43.6532,-79.3832&lt;br/&gt;relay.vantis.ninja,43.6532,-79.3832&lt;br/&gt;nostr-kyomu-haskell.onrender.com,37.7775,-122.397&lt;br/&gt;nostr-relay.amethyst.name,39.0067,-77.4291&lt;br/&gt;relay.bitcoindistrict.org,43.6532,-79.3832&lt;br/&gt;nos.xmark.cc,50.6924,3.20113&lt;br/&gt;relay01.lnfi.network,35.6764,139.65&lt;br/&gt;nostr-dev.wellorder.net,45.5201,-122.99&lt;br/&gt;nostr.rblb.it,43.7094,10.6582&lt;br/&gt;offchain.pub,39.1585,-94.5728&lt;br/&gt;wot.nostr.place,32.7767,-96.797&lt;br/&gt;fanfares.nostr1.com,38.6327,-90.1961&lt;br/&gt;ephemeral.snowflare.cc,43.6532,-79.3832&lt;br/&gt;relay.visionfusen.org,43.6532,-79.3832&lt;br/&gt;nostr.carroarmato0.be,51.0368,3.21186&lt;br/&gt;social.amanah.eblessing.co,48.1046,11.6002&lt;br/&gt;relay.cyphernomad.com,60.4032,25.0321&lt;br/&gt;nostr-rs-relay-qj1h.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ngengine.org,43.6532,-79.3832&lt;br/&gt;relay.nosto.re,51.1792,5.89444&lt;br/&gt;rusty-uat.siberian-albacore.ts.net:8443,35.6764,139.65&lt;br/&gt;nostr.luisschwab.net,43.6532,-79.3832&lt;br/&gt;nostr.aruku.ovh,1.27994,103.849&lt;br/&gt;srtrelay.c-stellar.net,43.6532,-79.3832&lt;br/&gt;nostr.tagomago.me,3.139,101.687&lt;br/&gt;relay.threenine.services,51.5222,-0.62916&lt;br/&gt;nostr.robosats.org,64.1476,-21.9392&lt;br/&gt;nostr.2b9t.xyz,34.0549,-118.243&lt;br/&gt;strfry.apps3.slidestr.net,40.4167,-3.70329&lt;br/&gt;kitchen.zap.cooking,43.6532,-79.3832&lt;br/&gt;relay.homeinhk.xyz,45.5152,-122.678&lt;br/&gt;relay.seq1.net,43.6532,-79.3832&lt;br/&gt;relay.bornheimer.app,50.1109,8.68213&lt;br/&gt;relay.vrtmrz.net,43.6532,-79.3832&lt;br/&gt;nostr.red5d.dev,43.6532,-79.3832&lt;br/&gt;relay-freeharmonypeople.space,38.7223,-9.13934&lt;br/&gt;aaa-api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;dev.relay.edufeed.org,49.4521,11.0767&lt;br/&gt;nostr.myshosholoza.co.za,52.3913,4.66545&lt;br/&gt;nostr.plantroon.com,50.1013,8.62643&lt;br/&gt;wot.dergigi.com,64.1476,-21.9392&lt;br/&gt;npub1spxdug4m3y24hpx5crm0el4zhkk0wafs8kp6m0xu0wecygqej2xqq8gyhx.fips.network,43.6532,-79.3832&lt;br/&gt;nostrelay.circum.space,52.3676,4.90414&lt;br/&gt;relay.dreamith.to,43.6532,-79.3832&lt;br/&gt;relay.nostriches.club,43.6532,-79.3832&lt;br/&gt;nostr-relayrs.gateway.in.th,15.5163,103.194&lt;br/&gt;nostr.chrissexton.org,43.6532,-79.3832&lt;br/&gt;relay.flashapp.me,43.652,-79.3633&lt;br/&gt;nostr-relay-1.trustlessenterprise.com,43.6532,-79.3832&lt;br/&gt;strfry.shock.network,39.0438,-77.4874&lt;br/&gt;relay.snotr.nl:49999,52.0195,4.42946&lt;br/&gt;spatia-arcana.com,34.0362,-118.443&lt;br/&gt;nostr.computingcache.com,34.0356,-118.442&lt;br/&gt;nostr.self-determined.de,53.5,10.25&lt;br/&gt;relay.sharegap.net,43.6532,-79.3832&lt;br/&gt;spookstr2.nostr1.com,38.6327,-90.1961&lt;br/&gt;v-relay.d02.vrtmrz.net,34.6937,135.502&lt;br/&gt;bridge.tagomago.me,3.139,101.687&lt;br/&gt;antiprimal.net,43.6532,-79.3832&lt;br/&gt;relay.nostrdice.com,-33.8688,151.209&lt;br/&gt;purpura.cloud,43.6532,-79.3832&lt;br/&gt;espelho.girino.org,43.6532,-79.3832&lt;br/&gt;relay.mostro.network,40.8302,-74.1299&lt;br/&gt;temp.iris.to,43.6532,-79.3832&lt;br/&gt;pyramid.self-determined.de,53.5,10.25&lt;br/&gt;relay.jeffg.fyi,43.6532,-79.3832&lt;br/&gt;nostr.aruku.kro.kr,37.3589,127.115&lt;br/&gt;chat-relay.zap-work.com,43.6532,-79.3832&lt;br/&gt;relay.islandbitcoin.com,12.8498,77.6545&lt;br/&gt;nostr.zoracle.org,45.6018,-121.185&lt;br/&gt;relay-dev.satlantis.io,40.8302,-74.1299&lt;br/&gt;relay.earthly.city,34.0362,-118.443&lt;br/&gt;speakeasy.cellar.social,49.4543,11.0746&lt;br/&gt;relay.bnos.space,43.6532,-79.3832&lt;br/&gt;relay.henryxplace.eu.org:9988,31.2304,121.474&lt;br/&gt;relay.bitmacro.cloud,43.6532,-79.3832&lt;br/&gt;nostr.thebiglake.org,32.71,-96.6745&lt;br/&gt;relay.lab.rytswd.com,49.4543,11.0746&lt;br/&gt;nostr.nadajnik.org,50.1109,8.68213&lt;br/&gt;relay.evanverma.com,40.8302,-74.1299&lt;br/&gt;relay2.angor.io,48.1046,11.6002&lt;br/&gt;prl.plus,55.7628,37.5983&lt;br/&gt;myvoiceourstory.org,37.3598,-121.981&lt;br/&gt;relay.arx-ccn.com,50.4754,12.3683&lt;br/&gt;wot.sudocarlos.com,43.6532,-79.3832&lt;br/&gt;relayrs.notoshi.win,43.6532,-79.3832&lt;br/&gt;nostrcity-club.fly.dev,48.8575,2.35138&lt;br/&gt;relay.tagayasu.xyz,45.4215,-75.6972&lt;br/&gt;nostr.blankfors.se,60.1699,24.9384&lt;br/&gt;nrs-01.darkcloudarcade.com,39.1008,-94.5811&lt;br/&gt;relay.lightning.pub,39.0438,-77.4874&lt;br/&gt;nostr-02.yakihonne.com,1.32123,103.695&lt;br/&gt;relay.nostrverse.net,43.6532,-79.3832&lt;br/&gt;nostr.wecsats.io,43.6532,-79.3832&lt;br/&gt;relay.illuminodes.com,47.6062,-122.332&lt;br/&gt;api.freefrom.space/v1/ws,43.6532,-79.3832&lt;br/&gt;nostr-relay.psfoundation.info,39.0438,-77.4874&lt;br/&gt;relay.samt.st,40.8302,-74.1299&lt;br/&gt;nostr-relay.cbrx.io,43.6532,-79.3832&lt;br/&gt;inbox.mycelium.social,38.627,-90.1994&lt;br/&gt;relay.anmore.me,49.281,-123.117&lt;br/&gt;no.str.cr,10.074,-84.2155&lt;br/&gt;nstr.a0a1.space,52.3563,4.95714&lt;br/&gt;relay.typedcypher.com,51.5072,-0.127586&lt;br/&gt;relay.bitmacro.pro,43.6532,-79.3832&lt;br/&gt;relay.nostrzh.org,43.6532,-79.3832&lt;br/&gt;ynostr.yael.at,60.1699,24.9384&lt;br/&gt;nostr-relay.zeabur.app,25.0797,121.234&lt;br/&gt;dynasty.libretechsystems.xyz,55.4724,9.87335&lt;br/&gt;nostr.bitcoiner.social,47.6743,-117.112&lt;br/&gt;nostr.girino.org,43.6532,-79.3832&lt;br/&gt;nostr2.girino.org,43.6532,-79.3832&lt;br/&gt;nostr-verified.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.fundstr.me,42.3601,-71.0589&lt;br/&gt;relay.mapboss.co.th,13.7234,100.784&lt;br/&gt;relay.qstr.app,51.5072,-0.127586&lt;br/&gt;nostr-rs-relay-ishosta.phamthanh.me,43.6532,-79.3832&lt;br/&gt;relay.klabo.world,47.674,-122.122&lt;br/&gt;relay.minibolt.info,43.6532,-79.3832&lt;br/&gt;x.kojira.io,43.6532,-79.3832&lt;br/&gt;relay-dev.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostriot.com,41.5695,-83.9786&lt;br/&gt;relayone.soundhsa.com,39.1008,-94.5811&lt;br/&gt;nr.yay.so,46.2126,6.1154&lt;br/&gt;relay.bithome.site,52.3563,4.95714&lt;br/&gt;relay.damus.io,43.6532,-79.3832&lt;br/&gt;nostr.mikoshi.de,50.1109,8.68213&lt;br/&gt;nostr.defucc.me,50.1109,8.68213&lt;br/&gt;relay.malxte.de,52.52,13.405&lt;br/&gt;relay.orangepill.ovh,49.1689,-0.358841&lt;br/&gt;bbw-nostr.xyz,41.5284,-87.4237&lt;br/&gt;kasztanowa.bieda.it,43.6532,-79.3832&lt;br/&gt;bitcoiner.social,47.6743,-117.112&lt;br/&gt;relay.lacompagniemaximus.com,45.3147,-73.8785&lt;br/&gt;relay.mostr.pub,43.6532,-79.3832&lt;br/&gt;relay.lanavault.space,60.1699,24.9384&lt;br/&gt;kotukonostr.onrender.com,37.7775,-122.397&lt;br/&gt;relay.ditto.pub,43.6532,-79.3832&lt;br/&gt;relay.erybody.com,41.4513,-81.7021&lt;br/&gt;nostr.dlcdevkit.com,40.0992,-83.1141&lt;br/&gt;ribo.us.nostria.app,41.5868,-93.625&lt;br/&gt;relay.paulstephenborile.com,49.4543,11.0746&lt;br/&gt;testnet-relay.samt.st,40.8302,-74.1299&lt;br/&gt;relay.purplefrog.cloud,35.6916,139.768&lt;br/&gt;relay.agorist.space,52.3734,4.89406&lt;br/&gt;nostr-relay.zimage.com,34.0549,-118.243&lt;br/&gt;nostr.azzamo.net,52.2633,21.0283&lt;br/&gt;strfry.elswa-dev.online,50.1109,8.68213&lt;br/&gt;wot.shaving.kiwi,43.6532,-79.3832&lt;br/&gt;okn.czas.plus,50.1109,8.68213&lt;br/&gt;bcast.seutoba.com.br,43.6532,-79.3832&lt;br/&gt;relay.sigit.io,50.4754,12.3683&lt;br/&gt;syb.lol,34.0549,-118.243&lt;br/&gt;relay.libernet.app,43.6532,-79.3832&lt;br/&gt;relay.angor.io,48.1046,11.6002&lt;br/&gt;relay.staging.commonshub.brussels,49.4543,11.0746&lt;br/&gt;strfry.atlantislabs.space,43.6532,-79.3832&lt;br/&gt;nostr.wom.wtf,43.6532,-79.3832&lt;br/&gt;nostrride.io,37.3986,-121.964&lt;br/&gt;nostr.dpinkerton.com,39.1008,-94.5811&lt;br/&gt;r.0kb.io,32.789,-96.7989&lt;br/&gt;nostr.hekster.org,37.3986,-121.964&lt;br/&gt;satsage.xyz,37.3986,-121.964&lt;br/&gt;nostr.islandarea.net,35.4669,-97.6473&lt;br/&gt;ve.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.openfarmtools.org,60.1699,24.9384&lt;br/&gt;top.testrelay.top,43.6532,-79.3832&lt;br/&gt;relay-rpi.edufeed.org,49.4521,11.0767&lt;br/&gt;pyramid.cult.cash,32.9483,-96.7299&lt;br/&gt;relay.edino.net,56.6268,47.9193&lt;br/&gt;nostr.snowbla.de,60.1699,24.9384&lt;br/&gt;relay.wavefunc.live,39.7392,-104.99&lt;br/&gt;tenex.chat,50.4754,12.3683&lt;br/&gt;relay.getsafebox.app,43.6532,-79.3832&lt;br/&gt;nostr.bond,50.1109,8.68213&lt;br/&gt;nostrelites.org,41.8781,-87.6298&lt;br/&gt;relay.plebeian.market,50.1109,8.68213&lt;br/&gt;relay.laantungir.net,-19.4692,-42.5315&lt;br/&gt;relay.decentnewsroom.com,50.4754,12.3683&lt;br/&gt;nostr-relay.nextblockvending.com,47.2343,-119.853&lt;br/&gt;relay.spacetomatoes.net,42.3601,-71.0589&lt;br/&gt;nostrbtc.com,43.6532,-79.3832&lt;br/&gt;relay.puresignal.news,43.6532,-79.3832&lt;br/&gt;relay-testnet.k8s.layer3.news,37.3387,-121.885&lt;br/&gt;relay.binaryrobot.com,43.6532,-79.3832&lt;br/&gt;relay.wavlake.com,41.2619,-95.8608&lt;br/&gt;inbox.scuba323.com,40.8218,-74.45&lt;br/&gt;nostr.spaceshell.xyz,43.6532,-79.3832&lt;br/&gt;relay.nostr.place,32.7767,-96.797&lt;br/&gt;holland-excited-charming-experiencing.trycloudflare.com,43.6532,-79.3832&lt;br/&gt;theoutpost.life,64.1476,-21.9392&lt;br/&gt;relay.fckstate.net,59.3293,18.0686&lt;br/&gt;bcast.girino.org,43.6532,-79.3832&lt;br/&gt;discovery.us.nostria.app,52.3676,4.90414&lt;br/&gt;relay.bullishbounty.com,43.6532,-79.3832&lt;br/&gt;nostr.88mph.life,51.5072,-0.127586&lt;br/&gt;nostr.tadryanom.me,43.6532,-79.3832&lt;br/&gt;nostr.sathoarder.com,48.5734,7.75211&lt;br/&gt;relay.nostr.net,43.6532,-79.3832&lt;br/&gt;zw.agorawlc.com,50.4754,12.3683&lt;br/&gt;relay.internationalright-wing.org,-22.5022,-48.7114&lt;br/&gt;nostr.vulpem.com,49.4543,11.0746&lt;br/&gt;wot.codingarena.top,50.4754,12.3683&lt;br/&gt;reraw.pbla2fish.cc,43.6532,-79.3832&lt;br/&gt;plebchain.club,43.6532,-79.3832&lt;br/&gt;orly-relay.imwald.eu,48.8575,2.35138&lt;br/&gt;relay.satnam.pub,43.6532,-79.3832&lt;br/&gt;cs-relay.nostrdev.com,50.4754,12.3683&lt;br/&gt;schnorr.me,43.6532,-79.3832&lt;br/&gt;nostr-relay.online,43.6532,-79.3832&lt;br/&gt;relay.routstr.com,43.6532,-79.3832&lt;br/&gt;relay.ohstr.com,43.6532,-79.3832&lt;br/&gt;relay.lanacoin-eternity.com,40.8302,-74.1299&lt;br/&gt;wot.nostr.net,43.6532,-79.3832&lt;br/&gt;nostr.ps1829.com,33.8851,130.883&lt;br/&gt;yabu.me,35.6092,139.73&lt;br/&gt;soloco.nl,43.6532,-79.3832&lt;br/&gt;librerelay.aaroniumii.com,43.6532,-79.3832&lt;br/&gt;relay.mmwaves.de,48.8575,2.35138&lt;br/&gt;relay.artx.market,43.6548,-79.3885&lt;br/&gt;nostr.jerrynya.fun,31.2304,121.474&lt;br/&gt;relay-arg.zombi.cloudrodion.com,1.35208,103.82&lt;br/&gt;relay.edufeed.org,49.4521,11.0767&lt;br/&gt;discovery.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.layer.systems,49.0291,8.35695&lt;br/&gt;nostr-rs-relay.dev.fedibtc.com,39.0438,-77.4874&lt;br/&gt;relay.0xchat.com,43.6532,-79.3832&lt;br/&gt;nos.lol,50.4754,12.3683&lt;br/&gt;lightning.red,53.3498,-6.26031&lt;br/&gt;slick.mjex.me,39.0418,-77.4744&lt;br/&gt;relay.boredvictor.xyz,41.3888,2.15899&lt;br/&gt;nostr.rtvslawenia.com,49.4543,11.0746&lt;br/&gt;relay.mitchelltribe.com,39.0438,-77.4874&lt;br/&gt;nostr.4rs.nl,49.0291,8.35696&lt;br/&gt;relay.olas.app,50.4754,12.3683&lt;br/&gt;memlay.v0l.io,53.3498,-6.26031&lt;br/&gt;nostr-01.yakihonne.com,1.29524,103.79&lt;br/&gt;relay.satmaxt.xyz,43.6532,-79.3832&lt;br/&gt;nostrcheck.tnsor.network,43.6532,-79.3832&lt;br/&gt;relay.guggero.org,46.0037,8.95105&lt;br/&gt;ai.techunder.tech:56711,22.5429,114.06&lt;br/&gt;premium.primal.net,43.6532,-79.3832&lt;br/&gt;nostr.tac.lol,47.4748,-122.273&lt;br/&gt;relay.zone667.com,60.1699,24.9384&lt;br/&gt;nostr-relay.gateway.in.th,15.5163,103.194&lt;br/&gt;vault.iris.to,43.6532,-79.3832&lt;br/&gt;strfry.bonsai.com,37.8716,-122.273&lt;br/&gt;ribo.eu.nostria.app,52.3676,4.90414&lt;br/&gt;relay.wellorder.net,45.5201,-122.99&lt;br/&gt;relay.tapestry.ninja,40.8054,-74.0241&lt;br/&gt;relay.dwadziesciajeden.pl,52.2297,21.0122&lt;br/&gt;relay.satlantis.io,32.8769,-80.0114&lt;br/&gt;nostr.pbfs.io,50.4754,12.3683&lt;br/&gt;freelay.sovbit.host,64.1476,-21.9392&lt;br/&gt;articles.layer3.news,37.3387,-121.885&lt;br/&gt;nostr.na.social,43.6532,-79.3832&lt;br/&gt;relay.fountain.fm,43.6532,-79.3832&lt;br/&gt;dev.relay.stream,43.6532,-79.3832&lt;br/&gt;nostr.n7ekb.net,36.1527,-95.9902&lt;br/&gt;relay5.bitransfer.org,43.6532,-79.3832&lt;br/&gt;relay.og.coop,43.6532,-79.3832&lt;br/&gt;nostr-server-production.up.railway.app,45.5019,-73.5674&lt;br/&gt;bucket.coracle.social,37.7775,-122.397&lt;br/&gt;relay.gulugulu.moe,43.6532,-79.3832&lt;br/&gt;relay.nostr-check.me,43.6532,-79.3832&lt;br/&gt;nostr.faultables.net,43.6532,-79.3832&lt;br/&gt;strfry.openhoofd.nl,51.9229,4.40833&lt;br/&gt;nostr.rblb.it:7777,43.7094,10.6582&lt;br/&gt;relay.nostrcheck.me,43.6532,-79.3832&lt;br/&gt;0x-nostr-relay.fly.dev,48.8575,2.35138&lt;br/&gt;nostr.thalheim.io,60.1699,24.9384&lt;br/&gt;relay-nl.zombi.cloudrodion.com,50.8943,6.06237&lt;br/&gt;relay.shadowbip.com,51.5072,-0.127586&lt;br/&gt;nostr-relay.corb.net,38.8353,-104.822&lt;br/&gt;purplerelay.com,43.6532,-79.3832&lt;br/&gt;nostr-pub.wellorder.net,45.5201,-122.99&lt;br/&gt;herbstmeister.com,34.0549,-118.243&lt;br/&gt;nostrcheck.me,43.6532,-79.3832&lt;br/&gt;pyramid.nostr.technology,52.3947,4.66399&lt;br/&gt;nostr.spicyz.io,43.6532,-79.3832&lt;br/&gt;nrs-02.darkcloudarcade.com,39.9526,-75.1652&lt;br/&gt;nestr.nedao.ch,47.0151,6.98832&lt;br/&gt;nostr.nodesmap.com,59.3327,18.0656&lt;br/&gt;nittom.nostr1.com,38.6327,-90.1961&lt;br/&gt;public.crostr.com,43.6532,-79.3832&lt;br/&gt;relay.cypherflow.ai,48.8575,2.35138&lt;br/&gt;nostr.bitczat.pl,60.1699,24.9384&lt;br/&gt;relayone.geektank.ai,39.1008,-94.5811&lt;br/&gt;testrelay.era21.space,43.6532,-79.3832&lt;br/&gt;relay.npubhaus.com,43.6532,-79.3832&lt;br/&gt;relay.bitmacro.io,48.8566,2.35222&lt;br/&gt;nostr.data.haus,50.4754,12.3683&lt;br/&gt;relay.credenso.cafe,43.3601,-80.3127&lt;br/&gt;relay.ru.ac.th,13.7607,100.627&lt;br/&gt;relay-fra.zombi.cloudrodion.com,48.8566,2.35222&lt;br/&gt;nostr.chaima.info,50.1109,8.68213&lt;br/&gt;nostr.mom,50.4754,12.3683
    </content>
    <updated>2026-04-03T16:50:55&#43;02:00</updated>
  </entry>

  <entry>
    <id>https://nostr.ae/nevent1qqsyddcvvdzmyyu0lxm7vfa7ed43ps6eeps5jrsfzxjypylt3fzsqpszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fjq3zt</id>
    
      <title type="html">#[tokio::main] #[cfg(feature = &amp;#34;nostr&amp;#34;)] async fn main() ...</title>
    
    <link rel="alternate" href="https://nostr.ae/nevent1qqsyddcvvdzmyyu0lxm7vfa7ed43ps6eeps5jrsfzxjypylt3fzsqpszypq7gr4vslayuq2p3wqen5swugk469uu0lvcpxm8lfx4k4hmqxcn5fjq3zt" />
    <content type="html">
      #[tokio::main]&lt;br/&gt;#[cfg(feature = &amp;#34;nostr&amp;#34;)]&lt;br/&gt;async fn main() {&lt;br/&gt;    use get_file_hash_core::publish_patch;&lt;br/&gt;    use nostr_sdk::Keys;&lt;br/&gt;    use nostr_sdk::EventId;&lt;br/&gt;    use std::str::FromStr;&lt;br/&gt;&lt;br/&gt;    let keys = Keys::generate();&lt;br/&gt;    let relay_urls = get_file_hash_core::get_relay_urls();&lt;br/&gt;    let d_tag = &amp;#34;my-awesome-repo-example&amp;#34;;&lt;br/&gt;    let commit_id = &amp;#34;a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0&amp;#34;; // Example commit ID&lt;br/&gt;&lt;br/&gt;    // Dummy EventId for examples that require a build_manifest_event_id&lt;br/&gt;    const DUMMY_BUILD_MANIFEST_ID_STR: &amp;amp;str = &amp;#34;f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0&amp;#34;;&lt;br/&gt;    let dummy_build_manifest_id = EventId::from_str(DUMMY_BUILD_MANIFEST_ID_STR).unwrap();&lt;br/&gt;&lt;br/&gt;    // Example 1: Without build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch without build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34; // Use an existing file for the patch content&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch without build_manifest_event_id published.&amp;#34;);&lt;br/&gt;&lt;br/&gt;    // Example 2: With build_manifest_event_id&lt;br/&gt;    println!(&amp;#34;Publishing patch with build_manifest_event_id...&amp;#34;);&lt;br/&gt;    publish_patch!(&lt;br/&gt;        &amp;amp;keys,&lt;br/&gt;        &amp;amp;relay_urls,&lt;br/&gt;        d_tag,&lt;br/&gt;        commit_id,&lt;br/&gt;        &amp;#34;../Cargo.toml&amp;#34;, // Use an existing file for the patch content&lt;br/&gt;        Some(&amp;amp;dummy_build_manifest_id)&lt;br/&gt;    );&lt;br/&gt;    println!(&amp;#34;Patch with build_manifest_event_id published.&amp;#34;);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;#[cfg(not(feature = &amp;#34;nostr&amp;#34;))]&lt;br/&gt;fn main() {&lt;br/&gt;    println!(&amp;#34;This example requires the &amp;#39;nostr&amp;#39; feature. Please run with: cargo run --example publish_patch --features nostr&amp;#34;);&lt;br/&gt;}&lt;br/&gt;
    </content>
    <updated>2026-04-03T16:48:13&#43;02:00</updated>
  </entry>

</feed>