A better Rust ATProto crate

binary releases on gh

Orual 6e6f55d9 8366b02d

Changed files
+323 -2
.github
workflows
crates
jacquard-common
nix
modules
+296
.github/workflows/release.yml
··· 1 + # This file was autogenerated by dist: https://axodotdev.github.io/cargo-dist 2 + # 3 + # Copyright 2022-2024, axodotdev 4 + # SPDX-License-Identifier: MIT or Apache-2.0 5 + # 6 + # CI that: 7 + # 8 + # * checks for a Git Tag that looks like a release 9 + # * builds artifacts with dist (archives, installers, hashes) 10 + # * uploads those artifacts to temporary workflow zip 11 + # * on success, uploads the artifacts to a GitHub Release 12 + # 13 + # Note that the GitHub Release will be created with a generated 14 + # title/body based on your changelogs. 15 + 16 + name: Release 17 + permissions: 18 + "contents": "write" 19 + 20 + # This task will run whenever you push a git tag that looks like a version 21 + # like "1.0.0", "v0.1.0-prerelease.1", "my-app/0.1.0", "releases/v1.0.0", etc. 22 + # Various formats will be parsed into a VERSION and an optional PACKAGE_NAME, where 23 + # PACKAGE_NAME must be the name of a Cargo package in your workspace, and VERSION 24 + # must be a Cargo-style SemVer Version (must have at least major.minor.patch). 25 + # 26 + # If PACKAGE_NAME is specified, then the announcement will be for that 27 + # package (erroring out if it doesn't have the given version or isn't dist-able). 28 + # 29 + # If PACKAGE_NAME isn't specified, then the announcement will be for all 30 + # (dist-able) packages in the workspace with that version (this mode is 31 + # intended for workspaces with only one dist-able package, or with all dist-able 32 + # packages versioned/released in lockstep). 33 + # 34 + # If you push multiple tags at once, separate instances of this workflow will 35 + # spin up, creating an independent announcement for each one. However, GitHub 36 + # will hard limit this to 3 tags per commit, as it will assume more tags is a 37 + # mistake. 38 + # 39 + # If there's a prerelease-style suffix to the version, then the release(s) 40 + # will be marked as a prerelease. 41 + on: 42 + pull_request: 43 + push: 44 + tags: 45 + - '**[0-9]+.[0-9]+.[0-9]+*' 46 + 47 + jobs: 48 + # Run 'dist plan' (or host) to determine what tasks we need to do 49 + plan: 50 + runs-on: "ubuntu-22.04" 51 + outputs: 52 + val: ${{ steps.plan.outputs.manifest }} 53 + tag: ${{ !github.event.pull_request && github.ref_name || '' }} 54 + tag-flag: ${{ !github.event.pull_request && format('--tag={0}', github.ref_name) || '' }} 55 + publishing: ${{ !github.event.pull_request }} 56 + env: 57 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 58 + steps: 59 + - uses: actions/checkout@v4 60 + with: 61 + persist-credentials: false 62 + submodules: recursive 63 + - name: Install dist 64 + # we specify bash to get pipefail; it guards against the `curl` command 65 + # failing. otherwise `sh` won't catch that `curl` returned non-0 66 + shell: bash 67 + run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.0/cargo-dist-installer.sh | sh" 68 + - name: Cache dist 69 + uses: actions/upload-artifact@v4 70 + with: 71 + name: cargo-dist-cache 72 + path: ~/.cargo/bin/dist 73 + # sure would be cool if github gave us proper conditionals... 74 + # so here's a doubly-nested ternary-via-truthiness to try to provide the best possible 75 + # functionality based on whether this is a pull_request, and whether it's from a fork. 76 + # (PRs run on the *source* but secrets are usually on the *target* -- that's *good* 77 + # but also really annoying to build CI around when it needs secrets to work right.) 78 + - id: plan 79 + run: | 80 + dist ${{ (!github.event.pull_request && format('host --steps=create --tag={0}', github.ref_name)) || 'plan' }} --output-format=json > plan-dist-manifest.json 81 + echo "dist ran successfully" 82 + cat plan-dist-manifest.json 83 + echo "manifest=$(jq -c "." plan-dist-manifest.json)" >> "$GITHUB_OUTPUT" 84 + - name: "Upload dist-manifest.json" 85 + uses: actions/upload-artifact@v4 86 + with: 87 + name: artifacts-plan-dist-manifest 88 + path: plan-dist-manifest.json 89 + 90 + # Build and packages all the platform-specific things 91 + build-local-artifacts: 92 + name: build-local-artifacts (${{ join(matrix.targets, ', ') }}) 93 + # Let the initial task tell us to not run (currently very blunt) 94 + needs: 95 + - plan 96 + if: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix.include != null && (needs.plan.outputs.publishing == 'true' || fromJson(needs.plan.outputs.val).ci.github.pr_run_mode == 'upload') }} 97 + strategy: 98 + fail-fast: false 99 + # Target platforms/runners are computed by dist in create-release. 100 + # Each member of the matrix has the following arguments: 101 + # 102 + # - runner: the github runner 103 + # - dist-args: cli flags to pass to dist 104 + # - install-dist: expression to run to install dist on the runner 105 + # 106 + # Typically there will be: 107 + # - 1 "global" task that builds universal installers 108 + # - N "local" tasks that build each platform's binaries and platform-specific installers 109 + matrix: ${{ fromJson(needs.plan.outputs.val).ci.github.artifacts_matrix }} 110 + runs-on: ${{ matrix.runner }} 111 + container: ${{ matrix.container && matrix.container.image || null }} 112 + env: 113 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 114 + BUILD_MANIFEST_NAME: target/distrib/${{ join(matrix.targets, '-') }}-dist-manifest.json 115 + steps: 116 + - name: enable windows longpaths 117 + run: | 118 + git config --global core.longpaths true 119 + - uses: actions/checkout@v4 120 + with: 121 + persist-credentials: false 122 + submodules: recursive 123 + - name: Install Rust non-interactively if not already installed 124 + if: ${{ matrix.container }} 125 + run: | 126 + if ! command -v cargo > /dev/null 2>&1; then 127 + curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 128 + echo "$HOME/.cargo/bin" >> $GITHUB_PATH 129 + fi 130 + - name: Install dist 131 + run: ${{ matrix.install_dist.run }} 132 + # Get the dist-manifest 133 + - name: Fetch local artifacts 134 + uses: actions/download-artifact@v4 135 + with: 136 + pattern: artifacts-* 137 + path: target/distrib/ 138 + merge-multiple: true 139 + - name: Install dependencies 140 + run: | 141 + ${{ matrix.packages_install }} 142 + - name: Build artifacts 143 + run: | 144 + # Actually do builds and make zips and whatnot 145 + dist build ${{ needs.plan.outputs.tag-flag }} --print=linkage --output-format=json ${{ matrix.dist_args }} > dist-manifest.json 146 + echo "dist ran successfully" 147 + - id: cargo-dist 148 + name: Post-build 149 + # We force bash here just because github makes it really hard to get values up 150 + # to "real" actions without writing to env-vars, and writing to env-vars has 151 + # inconsistent syntax between shell and powershell. 152 + shell: bash 153 + run: | 154 + # Parse out what we just built and upload it to scratch storage 155 + echo "paths<<EOF" >> "$GITHUB_OUTPUT" 156 + dist print-upload-files-from-manifest --manifest dist-manifest.json >> "$GITHUB_OUTPUT" 157 + echo "EOF" >> "$GITHUB_OUTPUT" 158 + 159 + cp dist-manifest.json "$BUILD_MANIFEST_NAME" 160 + - name: "Upload artifacts" 161 + uses: actions/upload-artifact@v4 162 + with: 163 + name: artifacts-build-local-${{ join(matrix.targets, '_') }} 164 + path: | 165 + ${{ steps.cargo-dist.outputs.paths }} 166 + ${{ env.BUILD_MANIFEST_NAME }} 167 + 168 + # Build and package all the platform-agnostic(ish) things 169 + build-global-artifacts: 170 + needs: 171 + - plan 172 + - build-local-artifacts 173 + runs-on: "ubuntu-22.04" 174 + env: 175 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 176 + BUILD_MANIFEST_NAME: target/distrib/global-dist-manifest.json 177 + steps: 178 + - uses: actions/checkout@v4 179 + with: 180 + persist-credentials: false 181 + submodules: recursive 182 + - name: Install cached dist 183 + uses: actions/download-artifact@v4 184 + with: 185 + name: cargo-dist-cache 186 + path: ~/.cargo/bin/ 187 + - run: chmod +x ~/.cargo/bin/dist 188 + # Get all the local artifacts for the global tasks to use (for e.g. checksums) 189 + - name: Fetch local artifacts 190 + uses: actions/download-artifact@v4 191 + with: 192 + pattern: artifacts-* 193 + path: target/distrib/ 194 + merge-multiple: true 195 + - id: cargo-dist 196 + shell: bash 197 + run: | 198 + dist build ${{ needs.plan.outputs.tag-flag }} --output-format=json "--artifacts=global" > dist-manifest.json 199 + echo "dist ran successfully" 200 + 201 + # Parse out what we just built and upload it to scratch storage 202 + echo "paths<<EOF" >> "$GITHUB_OUTPUT" 203 + jq --raw-output ".upload_files[]" dist-manifest.json >> "$GITHUB_OUTPUT" 204 + echo "EOF" >> "$GITHUB_OUTPUT" 205 + 206 + cp dist-manifest.json "$BUILD_MANIFEST_NAME" 207 + - name: "Upload artifacts" 208 + uses: actions/upload-artifact@v4 209 + with: 210 + name: artifacts-build-global 211 + path: | 212 + ${{ steps.cargo-dist.outputs.paths }} 213 + ${{ env.BUILD_MANIFEST_NAME }} 214 + # Determines if we should publish/announce 215 + host: 216 + needs: 217 + - plan 218 + - build-local-artifacts 219 + - build-global-artifacts 220 + # Only run if we're "publishing", and only if local and global didn't fail (skipped is fine) 221 + if: ${{ always() && needs.plan.outputs.publishing == 'true' && (needs.build-global-artifacts.result == 'skipped' || needs.build-global-artifacts.result == 'success') && (needs.build-local-artifacts.result == 'skipped' || needs.build-local-artifacts.result == 'success') }} 222 + env: 223 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 224 + runs-on: "ubuntu-22.04" 225 + outputs: 226 + val: ${{ steps.host.outputs.manifest }} 227 + steps: 228 + - uses: actions/checkout@v4 229 + with: 230 + persist-credentials: false 231 + submodules: recursive 232 + - name: Install cached dist 233 + uses: actions/download-artifact@v4 234 + with: 235 + name: cargo-dist-cache 236 + path: ~/.cargo/bin/ 237 + - run: chmod +x ~/.cargo/bin/dist 238 + # Fetch artifacts from scratch-storage 239 + - name: Fetch artifacts 240 + uses: actions/download-artifact@v4 241 + with: 242 + pattern: artifacts-* 243 + path: target/distrib/ 244 + merge-multiple: true 245 + - id: host 246 + shell: bash 247 + run: | 248 + dist host ${{ needs.plan.outputs.tag-flag }} --steps=upload --steps=release --output-format=json > dist-manifest.json 249 + echo "artifacts uploaded and released successfully" 250 + cat dist-manifest.json 251 + echo "manifest=$(jq -c "." dist-manifest.json)" >> "$GITHUB_OUTPUT" 252 + - name: "Upload dist-manifest.json" 253 + uses: actions/upload-artifact@v4 254 + with: 255 + # Overwrite the previous copy 256 + name: artifacts-dist-manifest 257 + path: dist-manifest.json 258 + # Create a GitHub Release while uploading all files to it 259 + - name: "Download GitHub Artifacts" 260 + uses: actions/download-artifact@v4 261 + with: 262 + pattern: artifacts-* 263 + path: artifacts 264 + merge-multiple: true 265 + - name: Cleanup 266 + run: | 267 + # Remove the granular manifests 268 + rm -f artifacts/*-dist-manifest.json 269 + - name: Create GitHub Release 270 + env: 271 + PRERELEASE_FLAG: "${{ fromJson(steps.host.outputs.manifest).announcement_is_prerelease && '--prerelease' || '' }}" 272 + ANNOUNCEMENT_TITLE: "${{ fromJson(steps.host.outputs.manifest).announcement_title }}" 273 + ANNOUNCEMENT_BODY: "${{ fromJson(steps.host.outputs.manifest).announcement_github_body }}" 274 + RELEASE_COMMIT: "${{ github.sha }}" 275 + run: | 276 + # Write and read notes from a file to avoid quoting breaking things 277 + echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt 278 + 279 + gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/* 280 + 281 + announce: 282 + needs: 283 + - plan 284 + - host 285 + # use "always() && ..." to allow us to wait for all publish jobs while 286 + # still allowing individual publish jobs to skip themselves (for prereleases). 287 + # "host" however must run to completion, no skipping allowed! 288 + if: ${{ always() && needs.host.result == 'success' }} 289 + runs-on: "ubuntu-22.04" 290 + env: 291 + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 292 + steps: 293 + - uses: actions/checkout@v4 294 + with: 295 + persist-credentials: false 296 + submodules: recursive
+6
Cargo.toml
··· 7 7 edition = "2024" 8 8 version = "0.5.3" 9 9 authors = ["Orual <orual@nonbinary.computer>"] 10 + #repository = "https://github.com/rsform/jacquard" 10 11 repository = "https://tangled.org/@nonbinary.computer/jacquard" 11 12 keywords = ["atproto", "at", "bluesky", "api", "client"] 12 13 categories = ["api-bindings", "web-programming::http-client"] ··· 76 77 # Crypto curves and JOSE 77 78 p256 = "0.13" 78 79 jose-jwk = "0.1" 80 + 81 + # The profile that 'dist' will build with 82 + [profile.dist] 83 + inherits = "release" 84 + lto = "thin"
+2 -2
crates/jacquard-common/Cargo.toml
··· 35 35 url.workspace = true 36 36 http.workspace = true 37 37 38 - reqwest = { workspace = true, optional = true, features = ["charset", "gzip", "stream"] } 38 + reqwest = { workspace = true, optional = true, features = ["json", "charset", "gzip", "stream"] } 39 39 serde_ipld_dagcbor.workspace = true 40 40 signature = { version = "2", optional = true } 41 41 tracing = { workspace = true, optional = true } ··· 49 49 getrandom = { version = "0.3.4", features = ["wasm_js"] } 50 50 51 51 [target.'cfg(not(target_arch = "wasm32"))'.dependencies] 52 - reqwest = { workspace = true, optional = true, features = ["http2", "system-proxy", "rustls-tls"] } 52 + reqwest = { workspace = true, optional = true, features = [ "http2", "system-proxy", "rustls-tls"] } 53 53 54 54 [features] 55 55 default = ["service-auth", "reqwest-client", "crypto"]
+17
dist-workspace.toml
··· 1 + [workspace] 2 + members = ["cargo:."] 3 + 4 + # Config for 'dist' 5 + [dist] 6 + # The preferred dist version to use in CI (Cargo.toml SemVer syntax) 7 + cargo-dist-version = "0.30.0" 8 + # CI backends to support 9 + ci = "github" 10 + # The installers to generate for each app 11 + installers = ["shell"] 12 + # Target platforms to build apps for (Rust target-triple syntax) 13 + targets = ["aarch64-apple-darwin", "aarch64-unknown-linux-gnu", "aarch64-pc-windows-msvc", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl", "x86_64-pc-windows-msvc"] 14 + # Path that installers should place binaries in 15 + install-path = "CARGO_HOME" 16 + # Whether to install an updater program 17 + install-updater = false
+2
nix/modules/devshell.nix
··· 19 19 rust-analyzer 20 20 cargo-release 21 21 cargo-semver-checks 22 + cargo-binstall 23 + cargo-dist 22 24 ]; 23 25 }; 24 26 };