diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8defc00..9f98242 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,14 +19,11 @@ jobs: os: [ubuntu-latest, macos-latest] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v5 - # The client library is a path dependency, so it has to be on disk beside this one. - uses: actions/checkout@v5 with: - repository: ergofobe/imogen-sdk - path: imogen-sdk-checkout - - name: Put the SDK where Cargo expects it - run: mv imogen-sdk-checkout ../imogen-sdk + # The client library is a submodule, so the commit being tested names the SDK + # commit it is tested against: re-running an old commit builds what it built. + submodules: recursive - uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy @@ -34,8 +31,11 @@ jobs: - name: Format run: cargo fmt --check - name: Lint - run: cargo clippy --all-targets -- -D warnings + run: cargo clippy --all-targets --locked -- -D warnings - name: Test - run: cargo test + run: cargo test --locked + # --locked everywhere above, so a submodule bump that left Cargo.lock behind fails + # here rather than at the next tag — the release build is the only thing that used + # to pass it, and by then the stale lockfile is already on main. - name: Build - run: cargo build --release + run: cargo build --release --locked diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2fe18ad..44e5b7f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -6,11 +6,6 @@ on: push: tags: ['v*'] workflow_dispatch: - inputs: - sdk_ref: - description: 'imogen-sdk ref to build against' - default: 'main' - type: string concurrency: group: ${{ github.workflow }}-${{ github.ref }} @@ -34,16 +29,11 @@ jobs: target: aarch64-unknown-linux-musl runs-on: ${{ matrix.runner }} steps: - - uses: actions/checkout@v5 - uses: actions/checkout@v5 with: - repository: ergofobe/imogen-sdk - # A path dependency, not a crates.io one, so a release is built against a - # named ref of it. A tag build takes main; a dispatch may say otherwise. - ref: ${{ inputs.sdk_ref || 'main' }} - path: imogen-sdk-checkout - - name: Put the SDK where Cargo expects it - run: mv imogen-sdk-checkout ../imogen-sdk + # The SDK is a submodule, so the tag being released names the SDK commit it is + # built against. Nothing has to remember to pin it. + submodules: recursive # musl, so one binary runs on any distribution rather than on whichever glibc the # runner happened to have. Nothing here links OpenSSL — TLS is rustls — so a fully @@ -105,16 +95,11 @@ jobs: name: macos · universal runs-on: macos-latest steps: - - uses: actions/checkout@v5 - uses: actions/checkout@v5 with: - repository: ergofobe/imogen-sdk - # A path dependency, not a crates.io one, so a release is built against a - # named ref of it. A tag build takes main; a dispatch may say otherwise. - ref: ${{ inputs.sdk_ref || 'main' }} - path: imogen-sdk-checkout - - name: Put the SDK where Cargo expects it - run: mv imogen-sdk-checkout ../imogen-sdk + # The SDK is a submodule, so the tag being released names the SDK commit it is + # built against. Nothing has to remember to pin it. + submodules: recursive - uses: dtolnay/rust-toolchain@stable with: diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..1fe3e62 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "imogen-sdk"] + path = imogen-sdk + url = https://github.com/ergofobe/imogen-sdk.git diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0e6dd45..d896bdd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,8 +1,7 @@ # Contributing ```bash -git clone https://github.com/ergofobe/imogen-sdk # a path dependency, beside this one -git clone https://github.com/ergofobe/imogen-cli +git clone --recurse-submodules https://github.com/ergofobe/imogen-cli cd imogen-cli cargo build @@ -12,9 +11,31 @@ cargo clippy --all-targets -- -D warnings ``` The client library lives in [imogen-sdk](https://github.com/ergofobe/imogen-sdk) and is -referenced by path, so the two repositories are checked out side by side. Anything that -touches the wire — a new endpoint, a new field — belongs there rather than here: this -program should contain no knowledge of HTTP at all. +vendored as a submodule at `imogen-sdk/`, so every commit here names the SDK commit it was +built and tested against. A clone made without `--recurse-submodules` — and any `git +worktree add`, which never populates submodules — leaves that directory empty and the build +unable to resolve the dependency: + +```bash +git submodule update --init --recursive +``` + +Changing the SDK means committing and merging there first, then bumping the pointer here — +CI fetches the submodule by commit, so a pointer at something that was never pushed fails +with `did not contain ` however well it built on your machine. Moving to a newer SDK is +then a commit like any other, and belongs in the pull request that needs it: + +```bash +git -C imogen-sdk fetch origin && git -C imogen-sdk checkout origin/main +cargo test --locked # a version bump there changes Cargo.lock here +git add imogen-sdk Cargo.lock && git commit -m "Move to the current SDK" +``` + +`--locked` is what CI runs, so the lockfile has to be committed alongside the pointer rather +than regenerated on the runner. + +Anything that touches the wire — a new endpoint, a new field — belongs there rather than +here: this program should contain no knowledge of HTTP at all. ## What to keep in mind diff --git a/Cargo.lock b/Cargo.lock index 4d8dfd1..9541d19 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -935,7 +935,7 @@ dependencies = [ [[package]] name = "imogen-sdk" -version = "0.1.0" +version = "0.2.0" dependencies = [ "base64", "futures", diff --git a/Cargo.toml b/Cargo.toml index 182fa0d..be3102d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,7 +30,7 @@ image = { version = "0.25", default-features = false, features = [ "tiff", "bmp", ] } -imogen-sdk = { path = "../imogen-sdk/rust" } +imogen-sdk = { path = "imogen-sdk/rust" } indicatif = "0.17" ratatui = "0.29" serde = { version = "1", features = ["derive"] } diff --git a/README.md b/README.md index cf5ad27..d1f7218 100644 --- a/README.md +++ b/README.md @@ -340,12 +340,16 @@ a downloaded binary will run: `xattr -d com.apple.quarantine imogen`. ## Building ```bash +git clone --recurse-submodules https://github.com/ergofobe/imogen-cli +cd imogen-cli cargo build --release ``` -The client library is [imogen-sdk](https://github.com/ergofobe/imogen-sdk), referenced by -path, so check it out beside this repository. Everything that touches the wire lives there; -this program contains no HTTP at all. +The client library is [imogen-sdk](https://github.com/ergofobe/imogen-sdk), vendored as a +submodule at `imogen-sdk/` and pinned to the commit this one is built against — so a clone +without `--recurse-submodules` needs `git submodule update --init --recursive` before it +will build. Everything that touches the wire lives there; this program contains no HTTP at +all. ## Licence diff --git a/imogen-sdk b/imogen-sdk new file mode 160000 index 0000000..9e6a17a --- /dev/null +++ b/imogen-sdk @@ -0,0 +1 @@ +Subproject commit 9e6a17a60f2bdf5d749d99c902ff3c13363ef2f8