yoto-cli 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,47 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ workflow_dispatch:
8
+
9
+ concurrency:
10
+ group: ${{ github.workflow }}-${{ github.ref }}
11
+ cancel-in-progress: true
12
+
13
+ jobs:
14
+ lint:
15
+ name: Lint
16
+ runs-on: ubuntu-latest
17
+ steps:
18
+ - uses: actions/checkout@v4
19
+ - uses: dtolnay/rust-toolchain@stable
20
+ with:
21
+ components: rustfmt, clippy
22
+ - name: Run linting
23
+ run: make lint
24
+
25
+ test:
26
+ name: Test
27
+ runs-on: ubuntu-latest
28
+ steps:
29
+ - uses: actions/checkout@v4
30
+ - uses: dtolnay/rust-toolchain@stable
31
+ - uses: taiki-e/install-action@nextest
32
+ - name: Run tests
33
+ run: make test
34
+
35
+ all-checks-passed:
36
+ name: All checks passed
37
+ runs-on: ubuntu-latest
38
+ needs: [lint, test]
39
+ if: always()
40
+ steps:
41
+ - name: Verify all checks passed
42
+ run: |
43
+ if [ "${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }}" == "true" ]; then
44
+ echo "Some checks failed or were cancelled"
45
+ exit 1
46
+ fi
47
+ echo "All checks passed"
@@ -0,0 +1,289 @@
1
+ name: Release
2
+
3
+ # Bootstrap the repo secrets this workflow needs once it is on GitHub:
4
+ # clihatch secrets rvben/yoto-cli # use --dry-run to preview
5
+ #
6
+ # Each target publishes in its own job, so one target's failure (for example a
7
+ # registry rate limit) does not block the others. Re-run only the failed target
8
+ # with: gh run rerun <run-id> --failed
9
+
10
+ on:
11
+ push:
12
+ tags:
13
+ - 'v[0-9]*.[0-9]*.[0-9]*'
14
+ workflow_dispatch:
15
+ inputs:
16
+ dry_run:
17
+ description: 'Dry run mode (skip actual publishing)'
18
+ required: false
19
+ default: true
20
+ type: boolean
21
+ skip_crates_io:
22
+ description: 'Skip publishing to crates.io (if already published)'
23
+ required: false
24
+ default: false
25
+ type: boolean
26
+ skip_pypi:
27
+ description: 'Skip publishing to PyPI (if already published)'
28
+ required: false
29
+ default: false
30
+ type: boolean
31
+
32
+ permissions:
33
+ contents: write
34
+
35
+ env:
36
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37
+ # Avoid the intermittent "HTTP2 framing layer" curl errors when cargo fetches
38
+ # from crates.io on GitHub-hosted runners.
39
+ CARGO_HTTP_MULTIPLEXING: "false"
40
+
41
+ jobs:
42
+ test:
43
+ name: Run tests
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v4
47
+ - uses: dtolnay/rust-toolchain@stable
48
+ - uses: taiki-e/install-action@nextest
49
+ - name: Verify Cargo.lock is up to date
50
+ run: cargo check --locked
51
+ - name: Run tests
52
+ run: make test
53
+
54
+ build:
55
+ name: Build ${{ matrix.target }}
56
+ needs: test
57
+ timeout-minutes: 30
58
+ strategy:
59
+ fail-fast: false
60
+ matrix:
61
+ include:
62
+ - os: ubuntu-22.04
63
+ target: x86_64-unknown-linux-gnu
64
+ - os: ubuntu-22.04-arm
65
+ target: aarch64-unknown-linux-gnu
66
+ - os: macos-14
67
+ target: aarch64-apple-darwin
68
+ # Cross-compiled on Apple Silicon (Intel mac runners are scarce).
69
+ - os: macos-14
70
+ target: x86_64-apple-darwin
71
+ cross: true
72
+ runs-on: ${{ matrix.os }}
73
+ steps:
74
+ - uses: actions/checkout@v4
75
+
76
+ - uses: dtolnay/rust-toolchain@stable
77
+ with:
78
+ targets: ${{ matrix.target }}
79
+
80
+ # Portable wheels: maturin-action builds linux wheels inside a manylinux
81
+ # container and macOS wheels natively.
82
+ - name: Build wheel
83
+ uses: PyO3/maturin-action@v1
84
+ with:
85
+ target: ${{ matrix.target }}
86
+ args: --release --out dist
87
+ manylinux: auto
88
+
89
+ - name: Build binary
90
+ run: cargo build --release --target ${{ matrix.target }}
91
+
92
+ - name: Verify binary
93
+ # Skip for cross-compiled targets the runner cannot execute.
94
+ if: ${{ !matrix.cross }}
95
+ run: ./target/${{ matrix.target }}/release/yoto-cli --version
96
+
97
+ - name: Create release archive
98
+ shell: bash
99
+ run: |
100
+ # GITHUB_REF_NAME is the tag on a release (v1.2.3) and the branch on
101
+ # a workflow_dispatch dry run (main); both are free of slashes.
102
+ VERSION="${GITHUB_REF_NAME}"
103
+ ARCHIVE_NAME="yoto-cli-${VERSION}-${{ matrix.target }}"
104
+ mkdir -p release-package
105
+ cp "target/${{ matrix.target }}/release/yoto-cli" release-package/yoto-cli
106
+ tar -czf "${ARCHIVE_NAME}.tar.gz" -C release-package yoto-cli
107
+ if [[ "${{ runner.os }}" == "macOS" ]]; then
108
+ shasum -a 256 "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
109
+ else
110
+ sha256sum "${ARCHIVE_NAME}.tar.gz" > "${ARCHIVE_NAME}.tar.gz.sha256"
111
+ fi
112
+ rm -rf release-package
113
+
114
+ - name: Upload wheel
115
+ uses: actions/upload-artifact@v4
116
+ with:
117
+ name: wheel-${{ matrix.target }}
118
+ path: dist/*.whl
119
+
120
+ - name: Upload release archives
121
+ uses: actions/upload-artifact@v4
122
+ with:
123
+ name: release-${{ matrix.target }}
124
+ path: |
125
+ yoto-cli-*-${{ matrix.target }}.tar.gz*
126
+
127
+ sdist:
128
+ name: Build source distribution
129
+ needs: test
130
+ runs-on: ubuntu-latest
131
+ steps:
132
+ - uses: actions/checkout@v4
133
+ - uses: astral-sh/setup-uv@v6
134
+ - name: Build sdist
135
+ run: uvx maturin sdist --out dist
136
+ - uses: actions/upload-artifact@v4
137
+ with:
138
+ name: sdist
139
+ path: dist/*.tar.gz
140
+
141
+ # crates.io publishes independently: a failure here does not block the other
142
+ # targets, and `gh run rerun --failed` retries only this job.
143
+ publish-crates:
144
+ name: Publish to crates.io
145
+ needs: build
146
+ runs-on: ubuntu-latest
147
+ steps:
148
+ - uses: actions/checkout@v4
149
+ - uses: dtolnay/rust-toolchain@stable
150
+
151
+ - name: Publish to crates.io
152
+ if: ${{ inputs.dry_run != true && inputs.skip_crates_io != true }}
153
+ env:
154
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
155
+ run: cargo publish --locked
156
+
157
+ - name: Test crates.io publish (dry run)
158
+ if: ${{ inputs.dry_run == true && inputs.skip_crates_io != true }}
159
+ run: cargo publish --dry-run --locked
160
+
161
+ - name: Skip crates.io publishing
162
+ if: ${{ inputs.skip_crates_io == true }}
163
+ run: echo "Skipping crates.io publishing as requested"
164
+
165
+ # PyPI publishes independently (isolating new-project rate limits, etc.).
166
+ publish-pypi:
167
+ name: Publish to PyPI
168
+ needs: [build, sdist]
169
+ runs-on: ubuntu-latest
170
+ steps:
171
+ - uses: astral-sh/setup-uv@v6
172
+ - name: Download wheels and sdist
173
+ uses: actions/download-artifact@v4
174
+ with:
175
+ path: artifacts
176
+ - name: Publish to PyPI
177
+ if: ${{ inputs.dry_run != true && inputs.skip_pypi != true }}
178
+ run: uv publish artifacts/wheel-*/*.whl artifacts/sdist/*.tar.gz
179
+ env:
180
+ UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
181
+ - name: Skip PyPI publishing
182
+ if: ${{ inputs.dry_run == true || inputs.skip_pypi == true }}
183
+ run: echo "Skipping PyPI publish (dry run or requested)"
184
+
185
+ github-release:
186
+ name: Create GitHub release
187
+ needs: build
188
+ if: ${{ inputs.dry_run != true }}
189
+ runs-on: ubuntu-latest
190
+ steps:
191
+ - name: Download release archives
192
+ uses: actions/download-artifact@v4
193
+ with:
194
+ pattern: release-*
195
+ path: artifacts
196
+ - name: Create Release
197
+ uses: softprops/action-gh-release@v2
198
+ with:
199
+ generate_release_notes: true
200
+ files: |
201
+ artifacts/release-*/yoto-cli-*.tar.gz
202
+ artifacts/release-*/yoto-cli-*.tar.gz.sha256
203
+
204
+ update-homebrew:
205
+ name: Update Homebrew tap
206
+ needs: github-release
207
+ if: ${{ inputs.dry_run != true }}
208
+ runs-on: ubuntu-latest
209
+ steps:
210
+ - name: Download release archives
211
+ uses: actions/download-artifact@v4
212
+ with:
213
+ pattern: release-*
214
+ path: /tmp/artifacts
215
+
216
+ - name: Compute SHA256 hashes
217
+ id: hashes
218
+ run: |
219
+ for target in x86_64-apple-darwin aarch64-apple-darwin x86_64-unknown-linux-gnu aarch64-unknown-linux-gnu; do
220
+ sha=$(cat /tmp/artifacts/release-${target}/yoto-cli-${{ github.ref_name }}-${target}.tar.gz.sha256 | awk '{print $1}')
221
+ key=$(echo "${target}" | tr '-' '_')
222
+ echo "${key}=${sha}" >> "$GITHUB_OUTPUT"
223
+ done
224
+
225
+ - name: Update Homebrew formula
226
+ env:
227
+ HOMEBREW_TAP_DEPLOY_KEY: ${{ secrets.HOMEBREW_TAP_DEPLOY_KEY }}
228
+ run: |
229
+ VERSION="${{ github.ref_name }}"
230
+ VERSION_NUM="${VERSION#v}"
231
+
232
+ cat > /tmp/yoto-cli.rb << 'FORMULA'
233
+ class YotoCli < Formula
234
+ desc "Manage Yoto Make Your Own playlists from the command line: sign in, upload audio, create and inspect content."
235
+ homepage "https://github.com/rvben/yoto-cli"
236
+ version "VERSION_NUM"
237
+ license "MIT"
238
+
239
+ on_macos do
240
+ if Hardware::CPU.arm?
241
+ url "https://github.com/rvben/yoto-cli/releases/download/VERSION/yoto-cli-VERSION-aarch64-apple-darwin.tar.gz"
242
+ sha256 "SHA_AARCH64_APPLE_DARWIN"
243
+ else
244
+ url "https://github.com/rvben/yoto-cli/releases/download/VERSION/yoto-cli-VERSION-x86_64-apple-darwin.tar.gz"
245
+ sha256 "SHA_X86_64_APPLE_DARWIN"
246
+ end
247
+ end
248
+
249
+ on_linux do
250
+ if Hardware::CPU.arm?
251
+ url "https://github.com/rvben/yoto-cli/releases/download/VERSION/yoto-cli-VERSION-aarch64-unknown-linux-gnu.tar.gz"
252
+ sha256 "SHA_AARCH64_UNKNOWN_LINUX_GNU"
253
+ else
254
+ url "https://github.com/rvben/yoto-cli/releases/download/VERSION/yoto-cli-VERSION-x86_64-unknown-linux-gnu.tar.gz"
255
+ sha256 "SHA_X86_64_UNKNOWN_LINUX_GNU"
256
+ end
257
+ end
258
+
259
+ def install
260
+ bin.install "yoto-cli"
261
+ end
262
+
263
+ test do
264
+ system "#{bin}/yoto-cli", "--version"
265
+ end
266
+ end
267
+ FORMULA
268
+
269
+ sed -i "s/VERSION_NUM/${VERSION_NUM}/g" /tmp/yoto-cli.rb
270
+ sed -i "s/VERSION/${VERSION}/g" /tmp/yoto-cli.rb
271
+ sed -i "s/SHA_AARCH64_APPLE_DARWIN/${{ steps.hashes.outputs.aarch64_apple_darwin }}/g" /tmp/yoto-cli.rb
272
+ sed -i "s/SHA_X86_64_APPLE_DARWIN/${{ steps.hashes.outputs.x86_64_apple_darwin }}/g" /tmp/yoto-cli.rb
273
+ sed -i "s/SHA_AARCH64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.aarch64_unknown_linux_gnu }}/g" /tmp/yoto-cli.rb
274
+ sed -i "s/SHA_X86_64_UNKNOWN_LINUX_GNU/${{ steps.hashes.outputs.x86_64_unknown_linux_gnu }}/g" /tmp/yoto-cli.rb
275
+
276
+ mkdir -p ~/.ssh
277
+ echo "$HOMEBREW_TAP_DEPLOY_KEY" > ~/.ssh/id_ed25519
278
+ chmod 600 ~/.ssh/id_ed25519
279
+ ssh-keyscan -t ed25519 github.com >> ~/.ssh/known_hosts 2>/dev/null
280
+
281
+ git clone git@github.com:rvben/homebrew-tap.git /tmp/tap
282
+ mkdir -p /tmp/tap/Formula
283
+ cp /tmp/yoto-cli.rb /tmp/tap/Formula/yoto-cli.rb
284
+ cd /tmp/tap
285
+ git config user.name "github-actions[bot]"
286
+ git config user.email "github-actions[bot]@users.noreply.github.com"
287
+ git add Formula/yoto-cli.rb
288
+ git diff --cached --quiet || git commit -m "Update yoto-cli to ${VERSION}"
289
+ git push
@@ -0,0 +1,4 @@
1
+ /target
2
+ /dist
3
+ .DS_Store
4
+ *.swp
@@ -0,0 +1,11 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/).
6
+
7
+ ## [0.1.0] - 2026-10-25
8
+
9
+ ### Added
10
+
11
+ - manage Yoto playlists and upload audio with covers and chapter icons ([cf45223](https://github.com/rvben/yoto-cli/commit/cf4522347260c65792e301d8552b942a9bfb67ba))