onde-cli 0.4.0__tar.gz → 0.4.2__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.
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.agents/AGENTS.md +1 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.agents/skills/distribution/SKILL.md +28 -0
- onde_cli-0.4.2/.github/workflows/release-crates.yml +217 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-github.yml +55 -6
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-homebrew.yml +1 -1
- onde_cli-0.4.2/.github/workflows/release-mcp-registry.yml +130 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-npm.yml +2 -4
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-nuget.yml +25 -4
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-pub.yml +1 -1
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/release-pypi.yml +2 -4
- onde_cli-0.4.2/.github/workflows/release-scoop.yml +148 -0
- onde_cli-0.4.2/.github/workflows/release-winget.yml +178 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.gitignore +3 -0
- onde_cli-0.4.2/.sigit/code-cloud-agent/config.toml +2 -0
- onde_cli-0.4.2/.sigit/code-review/config.toml +3 -0
- onde_cli-0.4.2/.sigit/factory/config.toml +9 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/AGENTS.md +1 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/CLAUDE.md +1 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/Cargo.lock +837 -303
- {onde_cli-0.4.0 → onde_cli-0.4.2}/Cargo.toml +2 -2
- {onde_cli-0.4.0 → onde_cli-0.4.2}/PKG-INFO +1 -1
- onde_cli-0.4.2/docs/mcp-registry.md +109 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/package-main.json.tmpl +1 -0
- onde_cli-0.4.2/packaging/winget/OndeInference.onde-cli.installer.yaml.in +18 -0
- onde_cli-0.4.2/packaging/winget/OndeInference.onde-cli.locale.en-US.yaml.in +34 -0
- onde_cli-0.4.2/packaging/winget/OndeInference.onde-cli.yaml.in +6 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/CHANGELOG.md +4 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/pubspec.yaml +1 -1
- onde_cli-0.4.2/server.json +81 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/chat.rs +7 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/main.rs +37 -1
- onde_cli-0.4.0/.github/workflows/release-crates.yml +0 -104
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.agents/skills/git/SKILL.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.github/workflows/ci.yml +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.nuget/NuGet/NuGet.Config +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/.nvmrc +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/LICENSE +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/README.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/assets/ondeinference-apps.png +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/build.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/README.md.tmpl +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/.gitignore +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/README.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/package-lock.json +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/package.json +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/src/index.ts +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/onde-cli/tsconfig.json +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/package.json.tmpl +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/scripts/render-main-package.cjs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/npm/scripts/render-platform-package.cjs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/nuget/.gitignore +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/nuget/onde-cli/Onde.Cli.csproj +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/nuget/onde-cli/Program.cs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/nuget/onde-cli/README.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/.gitignore +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/.pubignore +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/LICENSE +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/README.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/bin/onde.dart +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pub/onde_cli/lib/onde_cli.dart +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pypi/README.md +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pypi/pyproject.toml +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/pyproject.toml +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/rust-toolchain.toml +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/app.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/finetune.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/gguf.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/gresiq.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/hf.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/hf_clone.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/hf_search.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/hf_upload.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/mcp.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/merge.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/project.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/token.rs +0 -0
- {onde_cli-0.4.0 → onde_cli-0.4.2}/src/ui.rs +0 -0
|
@@ -64,6 +64,7 @@ The `onde` crate provides the inference engine (`onde::mistralrs`, a vendored mi
|
|
|
64
64
|
- **Commits:** include `Co-Authored-By: siGit Code <297239231+sigitc@users.noreply.github.com>` trailer when committing with the agent.
|
|
65
65
|
- **`[patch.crates-io]` and `path =` deps:** commented out in `Cargo.toml` for local dev against `onde`/`smbcloud-*`/`candle`. Never commit with these uncommented.
|
|
66
66
|
- **Distribution:** before touching any wrapper package (npm, PyPI, NuGet, pub.dev, Homebrew), read `.agents/skills/distribution/SKILL.md`. Keep all channel versions aligned with the Rust crate version in `Cargo.toml`.
|
|
67
|
+
- **MCP Registry:** the listing's ownership markers ship inside the published npm and NuGet artifacts, so a version published without them can never be listed. See `docs/mcp-registry.md` before touching `server.json` or either marker.
|
|
67
68
|
- **Wrapper packages** are in `npm/`, `pypi/`, `nuget/`, `pub/`. The npm base manifest is rewritten at release time by `npm/scripts/render-main-package.cjs`; do not hand-edit committed package.json versions as the source of truth for releases.
|
|
68
69
|
- **Clippy** runs with `-D warnings` in CI; all lints must pass.
|
|
69
70
|
- **Rust edition:** 2024; toolchain: stable.
|
|
@@ -110,6 +110,34 @@ If a wrapper uses one naming scheme and a workflow uploads another, the installe
|
|
|
110
110
|
|
|
111
111
|
## Release workflow principles
|
|
112
112
|
|
|
113
|
+
### One tag trigger, then fan out
|
|
114
|
+
|
|
115
|
+
`release-crates.yml` is the only workflow that reacts to a tag push. It verifies the
|
|
116
|
+
tag against `Cargo.toml` and `pubspec.yaml`, publishes the crate, then dispatches
|
|
117
|
+
`release-github`, `release-npm`, `release-nuget`, and `release-pypi` with the same tag.
|
|
118
|
+
`release-github` in turn dispatches `release-homebrew` and `release-pub` after the
|
|
119
|
+
release assets exist.
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
tag push
|
|
123
|
+
└─ release-crates (verify -> publish -> dispatch)
|
|
124
|
+
├─ release-github ─┬─ release-homebrew
|
|
125
|
+
│ └─ release-pub
|
|
126
|
+
├─ release-npm
|
|
127
|
+
├─ release-nuget
|
|
128
|
+
└─ release-pypi
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
This mirrors `smbcloud-cli`. Two properties matter:
|
|
132
|
+
|
|
133
|
+
- crates.io is the gate. If verify or publish fails, no wrapper publishes a version
|
|
134
|
+
that has no crate behind it.
|
|
135
|
+
- every dispatch passes `ref: <tag>`, not `ref: main`, so downstream workflows run the
|
|
136
|
+
workflow definition from the release state instead of whatever `main` happens to be.
|
|
137
|
+
|
|
138
|
+
Do not add `push: tags:` to a wrapper workflow. Several workflows racing on the same tag
|
|
139
|
+
is what lets the pub.dev launcher publish before its GitHub Release assets exist.
|
|
140
|
+
|
|
113
141
|
### Build first, package second
|
|
114
142
|
|
|
115
143
|
Always build native binaries in a target matrix first.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
name: Release crates.io
|
|
2
|
+
|
|
3
|
+
# This is the only workflow that reacts to a tag push. It verifies the tag,
|
|
4
|
+
# publishes the crate, and then dispatches every distribution workflow with the
|
|
5
|
+
# same tag. Wrappers never publish for a crate release that failed.
|
|
6
|
+
|
|
7
|
+
on:
|
|
8
|
+
push:
|
|
9
|
+
tags:
|
|
10
|
+
- "v*.*.*"
|
|
11
|
+
workflow_dispatch:
|
|
12
|
+
inputs:
|
|
13
|
+
tag:
|
|
14
|
+
description: "Release tag (e.g. v0.4.0)"
|
|
15
|
+
required: true
|
|
16
|
+
|
|
17
|
+
permissions:
|
|
18
|
+
contents: read
|
|
19
|
+
actions: write
|
|
20
|
+
|
|
21
|
+
concurrency:
|
|
22
|
+
group: release-crates-${{ github.ref }}
|
|
23
|
+
cancel-in-progress: false
|
|
24
|
+
|
|
25
|
+
env:
|
|
26
|
+
CARGO_TERM_COLOR: always
|
|
27
|
+
ONDE_APP_ID: ${{ secrets.ONDE_APP_ID }}
|
|
28
|
+
ONDE_APP_SECRET: ${{ secrets.ONDE_APP_SECRET }}
|
|
29
|
+
GRESIQ_API_KEY: ${{ secrets.GRESIQ_API_KEY }}
|
|
30
|
+
GRESIQ_API_SECRET: ${{ secrets.GRESIQ_API_SECRET }}
|
|
31
|
+
HF_TOKEN: ${{ secrets.HF_TOKEN }}
|
|
32
|
+
|
|
33
|
+
jobs:
|
|
34
|
+
verify:
|
|
35
|
+
name: Verify release
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
outputs:
|
|
38
|
+
version: ${{ steps.release.outputs.version }}
|
|
39
|
+
tag: ${{ steps.release.outputs.tag }}
|
|
40
|
+
steps:
|
|
41
|
+
- name: Checkout
|
|
42
|
+
uses: actions/checkout@v6
|
|
43
|
+
with:
|
|
44
|
+
ref: ${{ github.event.inputs.tag || github.ref }}
|
|
45
|
+
|
|
46
|
+
- name: Read Rust toolchain
|
|
47
|
+
shell: bash
|
|
48
|
+
run: |
|
|
49
|
+
rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
|
|
50
|
+
if [ -z "$rust_toolchain" ]; then
|
|
51
|
+
echo "Failed to read Rust toolchain from rust-toolchain.toml" >&2
|
|
52
|
+
exit 1
|
|
53
|
+
fi
|
|
54
|
+
echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
|
|
55
|
+
|
|
56
|
+
- name: Install Rust toolchain
|
|
57
|
+
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
|
|
58
|
+
with:
|
|
59
|
+
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
|
60
|
+
components: clippy, rustfmt
|
|
61
|
+
|
|
62
|
+
- name: Cache cargo registry and build artifacts
|
|
63
|
+
uses: Swatinem/rust-cache@v2
|
|
64
|
+
|
|
65
|
+
- name: Set the release version
|
|
66
|
+
id: release
|
|
67
|
+
shell: bash
|
|
68
|
+
run: |
|
|
69
|
+
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
|
|
70
|
+
release_tag="${GITHUB_REF_NAME}"
|
|
71
|
+
else
|
|
72
|
+
release_tag="${{ github.event.inputs.tag }}"
|
|
73
|
+
release_tag="${release_tag#refs/tags/}"
|
|
74
|
+
fi
|
|
75
|
+
release_version="${release_tag#v}"
|
|
76
|
+
|
|
77
|
+
echo "tag=${release_tag}" >> "$GITHUB_OUTPUT"
|
|
78
|
+
echo "version=${release_version}" >> "$GITHUB_OUTPUT"
|
|
79
|
+
|
|
80
|
+
- name: Ensure tag matches Cargo.toml version
|
|
81
|
+
shell: bash
|
|
82
|
+
run: |
|
|
83
|
+
version="$(sed -n 's/^version = "\(.*\)"/\1/p' Cargo.toml | head -n 1)"
|
|
84
|
+
if [ -z "$version" ]; then
|
|
85
|
+
echo "::error::Failed to read package version from Cargo.toml"
|
|
86
|
+
exit 1
|
|
87
|
+
fi
|
|
88
|
+
if [ "$version" != "${{ steps.release.outputs.version }}" ]; then
|
|
89
|
+
echo "::error::Cargo.toml is ${version} but the tag is ${{ steps.release.outputs.version }}"
|
|
90
|
+
exit 1
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
- name: Ensure the pub.dev wrapper matches the tag
|
|
94
|
+
shell: bash
|
|
95
|
+
run: |
|
|
96
|
+
pub_version="$(sed -n 's/^version: \(.*\)/\1/p' pub/onde_cli/pubspec.yaml | head -n 1)"
|
|
97
|
+
if [ "$pub_version" != "${{ steps.release.outputs.version }}" ]; then
|
|
98
|
+
echo "::error::pubspec.yaml is ${pub_version} but the tag is ${{ steps.release.outputs.version }}"
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
- name: Check formatting
|
|
103
|
+
run: cargo fmt --all -- --check
|
|
104
|
+
|
|
105
|
+
- name: Run clippy
|
|
106
|
+
run: cargo clippy --all-targets --all-features -- -D warnings
|
|
107
|
+
|
|
108
|
+
- name: Run tests
|
|
109
|
+
run: cargo test --all-features --locked --verbose
|
|
110
|
+
|
|
111
|
+
- name: Run cargo check
|
|
112
|
+
run: cargo check --locked
|
|
113
|
+
|
|
114
|
+
- name: Verify package contents
|
|
115
|
+
run: cargo package --locked --allow-dirty
|
|
116
|
+
|
|
117
|
+
publish:
|
|
118
|
+
name: Publish to crates.io
|
|
119
|
+
runs-on: ubuntu-latest
|
|
120
|
+
needs: verify
|
|
121
|
+
environment:
|
|
122
|
+
name: crates-io
|
|
123
|
+
permissions:
|
|
124
|
+
contents: read
|
|
125
|
+
steps:
|
|
126
|
+
- name: Checkout
|
|
127
|
+
uses: actions/checkout@v6
|
|
128
|
+
with:
|
|
129
|
+
ref: ${{ github.event.inputs.tag || github.ref }}
|
|
130
|
+
|
|
131
|
+
- name: Read Rust toolchain
|
|
132
|
+
shell: bash
|
|
133
|
+
run: |
|
|
134
|
+
rust_toolchain="$(sed -n 's/^channel = "\(.*\)"/\1/p' rust-toolchain.toml | head -n 1)"
|
|
135
|
+
echo "RUST_TOOLCHAIN=${rust_toolchain}" >> "$GITHUB_ENV"
|
|
136
|
+
|
|
137
|
+
- name: Install Rust toolchain
|
|
138
|
+
uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9
|
|
139
|
+
with:
|
|
140
|
+
toolchain: ${{ env.RUST_TOOLCHAIN }}
|
|
141
|
+
|
|
142
|
+
- name: Cache cargo registry and build artifacts
|
|
143
|
+
uses: Swatinem/rust-cache@v2
|
|
144
|
+
|
|
145
|
+
- name: Publish crate
|
|
146
|
+
env:
|
|
147
|
+
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
148
|
+
shell: bash
|
|
149
|
+
run: |
|
|
150
|
+
version="${{ needs.verify.outputs.version }}"
|
|
151
|
+
if curl -sSf "https://crates.io/api/v1/crates/onde-cli/${version}" >/dev/null 2>&1; then
|
|
152
|
+
echo "onde-cli ${version} is already on crates.io, skipping publish"
|
|
153
|
+
exit 0
|
|
154
|
+
fi
|
|
155
|
+
cargo publish --locked
|
|
156
|
+
|
|
157
|
+
dispatch-distributions:
|
|
158
|
+
name: Trigger distribution workflows
|
|
159
|
+
needs: [verify, publish]
|
|
160
|
+
runs-on: ubuntu-latest
|
|
161
|
+
|
|
162
|
+
steps:
|
|
163
|
+
- name: Trigger GitHub release
|
|
164
|
+
uses: actions/github-script@v7
|
|
165
|
+
with:
|
|
166
|
+
script: |
|
|
167
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
168
|
+
owner: context.repo.owner,
|
|
169
|
+
repo: context.repo.repo,
|
|
170
|
+
workflow_id: 'release-github.yml',
|
|
171
|
+
ref: '${{ needs.verify.outputs.tag }}',
|
|
172
|
+
inputs: {
|
|
173
|
+
tag: '${{ needs.verify.outputs.tag }}'
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
- name: Trigger npm release
|
|
178
|
+
uses: actions/github-script@v7
|
|
179
|
+
with:
|
|
180
|
+
script: |
|
|
181
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
182
|
+
owner: context.repo.owner,
|
|
183
|
+
repo: context.repo.repo,
|
|
184
|
+
workflow_id: 'release-npm.yml',
|
|
185
|
+
ref: '${{ needs.verify.outputs.tag }}',
|
|
186
|
+
inputs: {
|
|
187
|
+
tag: '${{ needs.verify.outputs.tag }}'
|
|
188
|
+
}
|
|
189
|
+
})
|
|
190
|
+
|
|
191
|
+
- name: Trigger NuGet release
|
|
192
|
+
uses: actions/github-script@v7
|
|
193
|
+
with:
|
|
194
|
+
script: |
|
|
195
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
196
|
+
owner: context.repo.owner,
|
|
197
|
+
repo: context.repo.repo,
|
|
198
|
+
workflow_id: 'release-nuget.yml',
|
|
199
|
+
ref: '${{ needs.verify.outputs.tag }}',
|
|
200
|
+
inputs: {
|
|
201
|
+
tag: '${{ needs.verify.outputs.tag }}'
|
|
202
|
+
}
|
|
203
|
+
})
|
|
204
|
+
|
|
205
|
+
- name: Trigger PyPI release
|
|
206
|
+
uses: actions/github-script@v7
|
|
207
|
+
with:
|
|
208
|
+
script: |
|
|
209
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
210
|
+
owner: context.repo.owner,
|
|
211
|
+
repo: context.repo.repo,
|
|
212
|
+
workflow_id: 'release-pypi.yml',
|
|
213
|
+
ref: '${{ needs.verify.outputs.tag }}',
|
|
214
|
+
inputs: {
|
|
215
|
+
tag: '${{ needs.verify.outputs.tag }}'
|
|
216
|
+
}
|
|
217
|
+
})
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
name: GitHub Release
|
|
2
2
|
|
|
3
|
+
# Dispatched by release-crates.yml once the crate publish succeeds.
|
|
3
4
|
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*.*.*"
|
|
7
5
|
workflow_dispatch:
|
|
8
6
|
inputs:
|
|
9
7
|
tag:
|
|
10
|
-
description: "Release tag (e.g. v0.
|
|
8
|
+
description: "Release tag (e.g. v0.4.0)"
|
|
11
9
|
required: true
|
|
12
10
|
|
|
13
11
|
permissions:
|
|
@@ -124,6 +122,25 @@ jobs:
|
|
|
124
122
|
echo "Archive: ${ARCHIVE_NAME}"
|
|
125
123
|
echo "SHA256: $(cat "${ARCHIVE_NAME}.sha256")"
|
|
126
124
|
|
|
125
|
+
# Scoop and winget consume the raw Windows binaries rather than a
|
|
126
|
+
# tarball, and both need a SHA256 sidecar. Windows runners use bash from
|
|
127
|
+
# Git for Windows, which has sha256sum; macOS only has shasum.
|
|
128
|
+
- name: Checksum release assets
|
|
129
|
+
shell: bash
|
|
130
|
+
run: |
|
|
131
|
+
cd release
|
|
132
|
+
for asset in *; do
|
|
133
|
+
case "${asset}" in *.sha256) continue ;; esac
|
|
134
|
+
|
|
135
|
+
if command -v sha256sum >/dev/null 2>&1; then
|
|
136
|
+
sha256sum "${asset}" | awk '{print $1}' > "${asset}.sha256"
|
|
137
|
+
else
|
|
138
|
+
shasum -a 256 "${asset}" | awk '{print $1}' > "${asset}.sha256"
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
echo "${asset}: $(cat "${asset}.sha256")"
|
|
142
|
+
done
|
|
143
|
+
|
|
127
144
|
- name: Upload binary artifact
|
|
128
145
|
uses: actions/upload-artifact@v4
|
|
129
146
|
with:
|
|
@@ -184,7 +201,7 @@ jobs:
|
|
|
184
201
|
owner: context.repo.owner,
|
|
185
202
|
repo: context.repo.repo,
|
|
186
203
|
workflow_id: 'release-homebrew.yml',
|
|
187
|
-
ref: '
|
|
204
|
+
ref: '${{ steps.tag.outputs.tag }}',
|
|
188
205
|
inputs: {
|
|
189
206
|
tag: '${{ steps.tag.outputs.tag }}'
|
|
190
207
|
}
|
|
@@ -199,9 +216,41 @@ jobs:
|
|
|
199
216
|
owner: context.repo.owner,
|
|
200
217
|
repo: context.repo.repo,
|
|
201
218
|
workflow_id: 'release-pub.yml',
|
|
202
|
-
ref: '
|
|
219
|
+
ref: '${{ steps.tag.outputs.tag }}',
|
|
203
220
|
inputs: {
|
|
204
221
|
tag: '${{ steps.tag.outputs.tag }}'
|
|
205
222
|
}
|
|
206
223
|
})
|
|
207
224
|
console.log('Dispatched release-pub.yml for tag ${{ steps.tag.outputs.tag }}')
|
|
225
|
+
|
|
226
|
+
# These channels publish outside this repo (a Scoop bucket,
|
|
227
|
+
# microsoft/winget-pkgs) and read checksums off the release created
|
|
228
|
+
# above, so they hang off this job rather than firing on the tag
|
|
229
|
+
# directly.
|
|
230
|
+
- name: Trigger OS package manager releases
|
|
231
|
+
uses: actions/github-script@v7
|
|
232
|
+
with:
|
|
233
|
+
script: |
|
|
234
|
+
const tag = '${{ steps.tag.outputs.tag }}'
|
|
235
|
+
const workflows = [
|
|
236
|
+
'release-scoop.yml',
|
|
237
|
+
'release-winget.yml',
|
|
238
|
+
]
|
|
239
|
+
|
|
240
|
+
for (const workflow_id of workflows) {
|
|
241
|
+
try {
|
|
242
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
243
|
+
owner: context.repo.owner,
|
|
244
|
+
repo: context.repo.repo,
|
|
245
|
+
workflow_id,
|
|
246
|
+
ref: tag,
|
|
247
|
+
inputs: { tag },
|
|
248
|
+
})
|
|
249
|
+
console.log(`Dispatched ${workflow_id} for tag ${tag}`)
|
|
250
|
+
} catch (error) {
|
|
251
|
+
// One packaging channel being unconfigured (a missing secret,
|
|
252
|
+
// a bucket repo that does not exist yet) should not take the
|
|
253
|
+
// rest of the fan-out down with it.
|
|
254
|
+
core.warning(`Failed to dispatch ${workflow_id}: ${error.message}`)
|
|
255
|
+
}
|
|
256
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
name: MCP Registry Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
inputs:
|
|
6
|
+
tag:
|
|
7
|
+
description: "Release tag (e.g. v0.4.1)"
|
|
8
|
+
required: true
|
|
9
|
+
|
|
10
|
+
# OIDC is how we authenticate to the MCP Registry: the registry trusts a GitHub
|
|
11
|
+
# Actions token issued for this repository, so no long-lived secret is needed.
|
|
12
|
+
permissions:
|
|
13
|
+
id-token: write
|
|
14
|
+
contents: read
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
publish:
|
|
18
|
+
name: Publish server.json to the MCP Registry
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
steps:
|
|
21
|
+
# Unlike the other release workflows, this one builds nothing from source:
|
|
22
|
+
# it uploads metadata. So it checks out the branch it was dispatched on
|
|
23
|
+
# rather than the tag — `server.json` may have landed after the tag was
|
|
24
|
+
# cut — and uses the tag input only to pick the version to publish.
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v6
|
|
27
|
+
|
|
28
|
+
- name: Set the release version
|
|
29
|
+
shell: bash
|
|
30
|
+
run: |
|
|
31
|
+
release_version="${{ github.event.inputs.tag }}"
|
|
32
|
+
release_version="${release_version#v}"
|
|
33
|
+
|
|
34
|
+
echo "RELEASE_VERSION=${release_version}" >> "$GITHUB_ENV"
|
|
35
|
+
|
|
36
|
+
- name: Check the server name is consistent across packages
|
|
37
|
+
shell: bash
|
|
38
|
+
run: |
|
|
39
|
+
server_name="$(jq -r '.name' server.json)"
|
|
40
|
+
echo "Server name: ${server_name}"
|
|
41
|
+
|
|
42
|
+
# npm proves ownership through `mcpName` in the published package.json,
|
|
43
|
+
# rendered at release time from this template.
|
|
44
|
+
grep -q "\"mcpName\": \"${server_name}\"" npm/package-main.json.tmpl
|
|
45
|
+
|
|
46
|
+
# NuGet proves ownership through an `mcp-name:` marker in the package README.
|
|
47
|
+
grep -q "mcp-name: ${server_name}" nuget/onde-cli/README.md
|
|
48
|
+
|
|
49
|
+
- name: Set the version in server.json
|
|
50
|
+
shell: bash
|
|
51
|
+
run: |
|
|
52
|
+
jq --arg v "${RELEASE_VERSION}" \
|
|
53
|
+
'.version = $v | .packages |= map(.version = $v)' \
|
|
54
|
+
server.json > server.tmp
|
|
55
|
+
mv server.tmp server.json
|
|
56
|
+
cat server.json
|
|
57
|
+
|
|
58
|
+
- name: Verify the published packages carry the ownership marker
|
|
59
|
+
shell: bash
|
|
60
|
+
run: |
|
|
61
|
+
# The registry stores metadata only, and validates it by fetching each
|
|
62
|
+
# listed package and looking for a marker naming this server. Checking
|
|
63
|
+
# the sources isn't enough: a package published before the marker
|
|
64
|
+
# landed will still be missing it. Both comparisons are case-sensitive.
|
|
65
|
+
server_name="$(jq -r '.name' server.json)"
|
|
66
|
+
|
|
67
|
+
# npm is queryable within seconds of publishing, but the npm release
|
|
68
|
+
# workflow may still be building its platform packages when this runs.
|
|
69
|
+
for attempt in $(seq 1 20); do
|
|
70
|
+
if npm view "@ondeinference/cli@${RELEASE_VERSION}" version; then
|
|
71
|
+
break
|
|
72
|
+
fi
|
|
73
|
+
if [ "${attempt}" -eq 20 ]; then
|
|
74
|
+
echo "@ondeinference/cli@${RELEASE_VERSION} is still not on npm after 10 minutes." >&2
|
|
75
|
+
exit 1
|
|
76
|
+
fi
|
|
77
|
+
echo "Waiting for @ondeinference/cli@${RELEASE_VERSION} on npm (attempt ${attempt}/20)..."
|
|
78
|
+
sleep 30
|
|
79
|
+
done
|
|
80
|
+
|
|
81
|
+
npm_mcp_name="$(npm view "@ondeinference/cli@${RELEASE_VERSION}" mcpName)"
|
|
82
|
+
if [ "${npm_mcp_name}" != "${server_name}" ]; then
|
|
83
|
+
echo "@ondeinference/cli@${RELEASE_VERSION} declares mcpName '${npm_mcp_name}', expected '${server_name}'." >&2
|
|
84
|
+
echo "npm versions are immutable — cut a new release with the marker in place." >&2
|
|
85
|
+
exit 1
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# nuget.org validates a package before it reaches the flat container,
|
|
89
|
+
# so a version pushed minutes ago is not queryable yet. Poll instead
|
|
90
|
+
# of failing the release on that race.
|
|
91
|
+
for attempt in $(seq 1 20); do
|
|
92
|
+
nuget_versions="$(curl -fsSL "https://api.nuget.org/v3-flatcontainer/onde.cli/index.json")"
|
|
93
|
+
if echo "${nuget_versions}" | jq -e --arg v "${RELEASE_VERSION}" '.versions | index($v)' >/dev/null; then
|
|
94
|
+
echo "Onde.Cli ${RELEASE_VERSION} is indexed."
|
|
95
|
+
break
|
|
96
|
+
fi
|
|
97
|
+
if [ "${attempt}" -eq 20 ]; then
|
|
98
|
+
echo "Onde.Cli ${RELEASE_VERSION} is still not indexed on nuget.org after 10 minutes." >&2
|
|
99
|
+
exit 1
|
|
100
|
+
fi
|
|
101
|
+
echo "Waiting for nuget.org to index ${RELEASE_VERSION} (attempt ${attempt}/20)..."
|
|
102
|
+
sleep 30
|
|
103
|
+
done
|
|
104
|
+
|
|
105
|
+
curl -fsSL -o package.nupkg \
|
|
106
|
+
"https://api.nuget.org/v3-flatcontainer/onde.cli/${RELEASE_VERSION}/onde.cli.${RELEASE_VERSION}.nupkg"
|
|
107
|
+
if ! unzip -p package.nupkg README.md | grep -q "mcp-name: ${server_name}"; then
|
|
108
|
+
echo "Onde.Cli ${RELEASE_VERSION} README is missing the 'mcp-name: ${server_name}' marker." >&2
|
|
109
|
+
exit 1
|
|
110
|
+
fi
|
|
111
|
+
rm package.nupkg
|
|
112
|
+
|
|
113
|
+
- name: Install mcp-publisher
|
|
114
|
+
shell: bash
|
|
115
|
+
run: |
|
|
116
|
+
curl -L "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
|
|
117
|
+
|
|
118
|
+
- name: Authenticate to the MCP Registry
|
|
119
|
+
shell: bash
|
|
120
|
+
run: ./mcp-publisher login github-oidc
|
|
121
|
+
|
|
122
|
+
- name: Publish
|
|
123
|
+
shell: bash
|
|
124
|
+
run: ./mcp-publisher publish
|
|
125
|
+
|
|
126
|
+
- name: Verify the server is listed
|
|
127
|
+
shell: bash
|
|
128
|
+
run: |
|
|
129
|
+
server_name="$(jq -r '.name' server.json)"
|
|
130
|
+
curl -fsSL "https://registry.modelcontextprotocol.io/v0.1/servers?search=${server_name}" | jq .
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
name: NPM Release
|
|
2
2
|
|
|
3
|
+
# Dispatched by release-crates.yml once the crate publish succeeds.
|
|
3
4
|
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*.*.*"
|
|
7
5
|
workflow_dispatch:
|
|
8
6
|
inputs:
|
|
9
7
|
tag:
|
|
10
|
-
description: "Release tag (e.g. v0.
|
|
8
|
+
description: "Release tag (e.g. v0.4.0)"
|
|
11
9
|
required: true
|
|
12
10
|
|
|
13
11
|
permissions:
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
name: NuGet Release
|
|
2
2
|
|
|
3
|
+
# Dispatched by release-crates.yml once the crate publish succeeds.
|
|
3
4
|
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*.*.*"
|
|
7
5
|
workflow_dispatch:
|
|
8
6
|
inputs:
|
|
9
7
|
tag:
|
|
10
|
-
description: "Release tag (e.g. v0.
|
|
8
|
+
description: "Release tag (e.g. v0.4.0)"
|
|
11
9
|
required: true
|
|
12
10
|
|
|
13
11
|
permissions:
|
|
@@ -303,3 +301,26 @@ jobs:
|
|
|
303
301
|
--api-key "${NUGET_API_KEY}" \
|
|
304
302
|
--source https://api.nuget.org/v3/index.json \
|
|
305
303
|
--skip-duplicate
|
|
304
|
+
|
|
305
|
+
dispatch-mcp-registry:
|
|
306
|
+
name: Trigger MCP Registry release
|
|
307
|
+
needs: publish-nuget
|
|
308
|
+
runs-on: ubuntu-latest
|
|
309
|
+
permissions:
|
|
310
|
+
actions: write
|
|
311
|
+
steps:
|
|
312
|
+
# The MCP Registry listing needs both npm and NuGet live at this version,
|
|
313
|
+
# and NuGet is the slower of the two, so it hangs off this workflow rather
|
|
314
|
+
# than the fan-out in release-crates.yml.
|
|
315
|
+
- name: Trigger MCP Registry release workflow
|
|
316
|
+
uses: actions/github-script@v7
|
|
317
|
+
with:
|
|
318
|
+
script: |
|
|
319
|
+
const tag = '${{ github.event.inputs.tag }}' || context.ref.replace('refs/tags/', '')
|
|
320
|
+
await github.rest.actions.createWorkflowDispatch({
|
|
321
|
+
owner: context.repo.owner,
|
|
322
|
+
repo: context.repo.repo,
|
|
323
|
+
workflow_id: 'release-mcp-registry.yml',
|
|
324
|
+
ref: tag,
|
|
325
|
+
inputs: { tag }
|
|
326
|
+
})
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
name: PyPI Release
|
|
2
2
|
|
|
3
|
+
# Dispatched by release-crates.yml once the crate publish succeeds.
|
|
3
4
|
on:
|
|
4
|
-
push:
|
|
5
|
-
tags:
|
|
6
|
-
- "v*.*.*"
|
|
7
5
|
workflow_dispatch:
|
|
8
6
|
inputs:
|
|
9
7
|
tag:
|
|
10
|
-
description: "Release tag (e.g. v0.
|
|
8
|
+
description: "Release tag (e.g. v0.4.0)"
|
|
11
9
|
required: true
|
|
12
10
|
|
|
13
11
|
permissions:
|