openwebui-mcp-server 0.2.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.
- openwebui_mcp_server-0.2.0/.actrc +19 -0
- openwebui_mcp_server-0.2.0/.github/RELEASE_CHECKLIST.md +106 -0
- openwebui_mcp_server-0.2.0/.github/workflows/FINAL_SUMMARY.md +289 -0
- openwebui_mcp_server-0.2.0/.github/workflows/IMPROVEMENTS.md +289 -0
- openwebui_mcp_server-0.2.0/.github/workflows/PUBLISH_GUIDE.md +328 -0
- openwebui_mcp_server-0.2.0/.github/workflows/SUMMARY.md +284 -0
- openwebui_mcp_server-0.2.0/.github/workflows/publish.yml +247 -0
- openwebui_mcp_server-0.2.0/.gitignore +59 -0
- openwebui_mcp_server-0.2.0/.python-version +1 -0
- openwebui_mcp_server-0.2.0/Dockerfile +30 -0
- openwebui_mcp_server-0.2.0/LICENSE +21 -0
- openwebui_mcp_server-0.2.0/PKG-INFO +247 -0
- openwebui_mcp_server-0.2.0/README.md +221 -0
- openwebui_mcp_server-0.2.0/compose.yaml +77 -0
- openwebui_mcp_server-0.2.0/mise.fork.toml +19 -0
- openwebui_mcp_server-0.2.0/mise.toml +217 -0
- openwebui_mcp_server-0.2.0/pyproject.toml +58 -0
- openwebui_mcp_server-0.2.0/scripts/init-api-key.sh +117 -0
- openwebui_mcp_server-0.2.0/specs/open-webui.openapi.json +35171 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/__init__.py +1 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/auth.py +30 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/client.py +740 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/main.py +44 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/models.py +215 -0
- openwebui_mcp_server-0.2.0/src/openwebui_mcp/server.py +704 -0
- openwebui_mcp_server-0.2.0/tests/__init__.py +1 -0
- openwebui_mcp_server-0.2.0/tests/test_client_changes.py +681 -0
- openwebui_mcp_server-0.2.0/tests/test_integration.py +211 -0
- openwebui_mcp_server-0.2.0/tests/test_mcp_wrapper_logic.py +41 -0
- openwebui_mcp_server-0.2.0/uv.lock +1835 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
--workflows $PWD/.github//workflows/
|
|
2
|
+
--artifact-server-path $PWD/.github/act-artifacts/
|
|
3
|
+
--artifact-server-addr 10.136.229.19
|
|
4
|
+
--artifact-server-port 34567
|
|
5
|
+
--defaultbranch main
|
|
6
|
+
--var PACKAGE_NAME=$PYPI_PACKAGE_NAME
|
|
7
|
+
--var RUNS_ON=[ "self-hosted", "ubuntu-latest" ]
|
|
8
|
+
--secret GITHUB_TOKEN=$GITHUB_TOKEN
|
|
9
|
+
--secret PYPI_API_TOKEN=$PYPI_API_TOKEN
|
|
10
|
+
--secret TEST_PYPI_API_TOKEN=$TEST_PYPI_API_TOKEN
|
|
11
|
+
--actor $GITHUB_REPOSITORY_SLUG
|
|
12
|
+
--env GITHUB_WORKFLOW_REF=$GITHUB_REPOSITORY_SLUG/.github/workflows/publish.yml
|
|
13
|
+
--env UV_LINK_MODE=copy
|
|
14
|
+
--remote-name $GITHUB_REPOSITORY_REMOTE
|
|
15
|
+
--strict
|
|
16
|
+
--container-daemon-socket $DOCKER_HOST_SOCKET
|
|
17
|
+
#--verbose
|
|
18
|
+
#--validate
|
|
19
|
+
#--watch
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Production Release Checklist
|
|
2
|
+
|
|
3
|
+
Use this checklist before every production release to ensure a smooth deployment.
|
|
4
|
+
|
|
5
|
+
## Pre-Release (Local)
|
|
6
|
+
|
|
7
|
+
### Code Quality
|
|
8
|
+
- [ ] All tests pass: `mise run owu:tests:all`
|
|
9
|
+
- [ ] Linter passes: `mise run owu:linter:check`
|
|
10
|
+
- [ ] No uncommitted changes: `git status`
|
|
11
|
+
- [ ] Branch is up to date: `git pull origin main`
|
|
12
|
+
|
|
13
|
+
### Version Management
|
|
14
|
+
- [ ] Version follows semantic versioning (MAJOR.MINOR.PATCH)
|
|
15
|
+
- [ ] CHANGELOG.md is updated (if using)
|
|
16
|
+
- [ ] Breaking changes are documented
|
|
17
|
+
|
|
18
|
+
### Documentation
|
|
19
|
+
- [ ] README.md reflects new features/changes
|
|
20
|
+
- [ ] API documentation is up to date
|
|
21
|
+
- [ ] Migration guide for breaking changes
|
|
22
|
+
|
|
23
|
+
### Dependencies
|
|
24
|
+
- [ ] `uv.lock` is up to date: `uv lock`
|
|
25
|
+
- [ ] No security vulnerabilities: `uv pip audit` (if available)
|
|
26
|
+
|
|
27
|
+
## Release Process
|
|
28
|
+
|
|
29
|
+
### Option 1: Automated (Recommended)
|
|
30
|
+
```bash
|
|
31
|
+
# Run all checks and create tag
|
|
32
|
+
mise run release:prepare X.Y.Z
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### Option 2: Manual
|
|
36
|
+
```bash
|
|
37
|
+
# 1. Run checks
|
|
38
|
+
mise run owu:linter:check
|
|
39
|
+
mise run owu:tests:all
|
|
40
|
+
|
|
41
|
+
# 2. Bump version
|
|
42
|
+
mise run bump:patch # or minor/major
|
|
43
|
+
|
|
44
|
+
# 3. Commit and tag
|
|
45
|
+
git add pyproject.toml
|
|
46
|
+
git commit -m "chore: bump version to X.Y.Z"
|
|
47
|
+
git tag -a vX.Y.Z -m "Release vX.Y.Z"
|
|
48
|
+
git push origin main vX.Y.Z
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Post-Release Verification
|
|
52
|
+
|
|
53
|
+
### GitHub Actions
|
|
54
|
+
- [ ] Build job completed successfully
|
|
55
|
+
- [ ] Publish to Test PyPI succeeded
|
|
56
|
+
- [ ] Publish to PyPI succeeded (after approval)
|
|
57
|
+
- [ ] GitHub Release created
|
|
58
|
+
|
|
59
|
+
### PyPI
|
|
60
|
+
- [ ] Package appears on https://pypi.org/project/openwebui-mcp-server/
|
|
61
|
+
- [ ] Version number is correct
|
|
62
|
+
- [ ] Package metadata is correct
|
|
63
|
+
|
|
64
|
+
### Installation Test
|
|
65
|
+
```bash
|
|
66
|
+
# Wait 5-10 minutes for PyPI CDN
|
|
67
|
+
pip install openwebui-mcp-server==X.Y.Z
|
|
68
|
+
openwebui-mcp --version
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Documentation
|
|
72
|
+
- [ ] GitHub Release notes are accurate
|
|
73
|
+
- [ ] Installation instructions work
|
|
74
|
+
- [ ] No broken links in documentation
|
|
75
|
+
|
|
76
|
+
## Emergency Rollback
|
|
77
|
+
|
|
78
|
+
If a bad release is published:
|
|
79
|
+
|
|
80
|
+
1. **Yank the release** (preferred):
|
|
81
|
+
```bash
|
|
82
|
+
pip install twine
|
|
83
|
+
twine yank openwebui-mcp-server==X.Y.Z
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
2. **Publish hotfix**:
|
|
87
|
+
```bash
|
|
88
|
+
# Fix the issue
|
|
89
|
+
mise run bump:patch
|
|
90
|
+
git add pyproject.toml
|
|
91
|
+
git commit -m "fix: hotfix for vX.Y.Z"
|
|
92
|
+
git tag -a vX.Y.(Z+1) -m "Hotfix release vX.Y.(Z+1)"
|
|
93
|
+
git push origin main vX.Y.(Z+1)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
3. **Notify users**:
|
|
97
|
+
- Create GitHub issue explaining the problem
|
|
98
|
+
- Update README with known issues
|
|
99
|
+
- Post announcement if critical
|
|
100
|
+
|
|
101
|
+
## Notes
|
|
102
|
+
|
|
103
|
+
- Never reuse version numbers
|
|
104
|
+
- Always test installation after release
|
|
105
|
+
- Monitor GitHub Actions for any failures
|
|
106
|
+
- Keep rollback procedure ready
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Production Workflow - Final Summary
|
|
2
|
+
|
|
3
|
+
## Critical Questions Answered
|
|
4
|
+
|
|
5
|
+
### 1. Tag Creation: Do we create `v*` tags?
|
|
6
|
+
|
|
7
|
+
**YES** - Tags must be created manually by maintainers.
|
|
8
|
+
|
|
9
|
+
**When to create tags**:
|
|
10
|
+
- After all PRs for a release are merged to main
|
|
11
|
+
- After running `mise run release:check` successfully
|
|
12
|
+
- When ready to publish to production PyPI
|
|
13
|
+
|
|
14
|
+
**How to create tags** (using proper mise syntax):
|
|
15
|
+
```bash
|
|
16
|
+
# Automated (recommended)
|
|
17
|
+
mise run release:prepare 0.2.0
|
|
18
|
+
|
|
19
|
+
# Just create the tag
|
|
20
|
+
mise run release:tag 0.2.0
|
|
21
|
+
|
|
22
|
+
# Just run pre-release checks
|
|
23
|
+
mise run release:check
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
**Mise tasks use the `usage` field for arguments**:
|
|
27
|
+
```toml
|
|
28
|
+
[tasks."release:tag"]
|
|
29
|
+
usage = 'arg "<version>" help="Version to release (e.g., 0.2.0)"'
|
|
30
|
+
run = """
|
|
31
|
+
VERSION="${usage_version}"
|
|
32
|
+
...
|
|
33
|
+
"""
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
### 2. Artifact Visibility: Can we see artifacts?
|
|
39
|
+
|
|
40
|
+
**YES** - Artifacts are visible in GitHub Actions UI.
|
|
41
|
+
|
|
42
|
+
**Where to find them**:
|
|
43
|
+
1. Go to: https://github.com/stephanschielke/open-webui-mcp-server/actions
|
|
44
|
+
2. Click on a completed workflow run
|
|
45
|
+
3. Scroll to "Artifacts" section at the bottom
|
|
46
|
+
4. Download `python-package-distributions`
|
|
47
|
+
|
|
48
|
+
**Artifact contents**:
|
|
49
|
+
- `dist/*.whl` - Built wheel distribution
|
|
50
|
+
- `dist/*.tar.gz` - Source distribution
|
|
51
|
+
|
|
52
|
+
**Retention**: 5 days for remote GitHub, 1 day for local act
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### 3. ghalint: Should it be a job or step?
|
|
57
|
+
|
|
58
|
+
**IMPLEMENTED as a step** in the build job.
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
- name: Validate workflow
|
|
62
|
+
run: mise run owu:gha:lint
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Benefits**:
|
|
66
|
+
- Catches workflow security issues early
|
|
67
|
+
- No separate job overhead
|
|
68
|
+
- Fails fast if workflow has problems
|
|
69
|
+
- Runs on every push
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
### 4. Rebuild: Do we need to rebuild with artifacts?
|
|
74
|
+
|
|
75
|
+
**YES** - Rebuilding is necessary for production releases.
|
|
76
|
+
|
|
77
|
+
**Why**:
|
|
78
|
+
1. The `build` job artifact has dev version (e.g., `0.2.0.dev1`)
|
|
79
|
+
2. Production needs release version (e.g., `0.2.0`)
|
|
80
|
+
3. We set version from tag, then rebuild
|
|
81
|
+
|
|
82
|
+
**Flow**:
|
|
83
|
+
```
|
|
84
|
+
build job → artifact (0.2.0.dev1)
|
|
85
|
+
↓
|
|
86
|
+
publish-release → download → set version (0.2.0) → rebuild → publish
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
**This is correct** because:
|
|
90
|
+
- Build job runs on every push (needs dev version)
|
|
91
|
+
- Release job only runs on tags (needs release version)
|
|
92
|
+
- Rebuilding ensures correct version in package
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### 5. OIDC vs API Token: Should we use OIDC?
|
|
97
|
+
|
|
98
|
+
**YES** - OIDC is now implemented!
|
|
99
|
+
|
|
100
|
+
**Current state**:
|
|
101
|
+
- Test PyPI: Already using OIDC (trusted publishing configured)
|
|
102
|
+
- Production PyPI: Now using OIDC (workflow updated)
|
|
103
|
+
|
|
104
|
+
**Security benefits**:
|
|
105
|
+
| Aspect | API Token | OIDC |
|
|
106
|
+
|--------|-----------|------|
|
|
107
|
+
| Lifespan | Months/years | 15 minutes max |
|
|
108
|
+
| Secret required | Yes | No |
|
|
109
|
+
| Rotation | Manual | Automatic |
|
|
110
|
+
| Leak risk | High | Low |
|
|
111
|
+
| Audit trail | Limited | Full |
|
|
112
|
+
|
|
113
|
+
**Migration steps**:
|
|
114
|
+
1. ✅ Configure trusted publisher on PyPI
|
|
115
|
+
2. ✅ Update workflow to use OIDC
|
|
116
|
+
3. ⏳ Test with a release
|
|
117
|
+
4. ⏳ Remove `PYPI_ACCOUNT_API_TOKEN` after verification
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
## Files Created/Modified
|
|
122
|
+
|
|
123
|
+
### Modified Files
|
|
124
|
+
1. `.github/workflows/publish.yml`
|
|
125
|
+
- Added ghalint validation step
|
|
126
|
+
- Implemented OIDC for production PyPI
|
|
127
|
+
- Added version validation
|
|
128
|
+
- Added GitHub Release job with changelog
|
|
129
|
+
- Fixed persist-credentials warning
|
|
130
|
+
|
|
131
|
+
2. `mise.toml`
|
|
132
|
+
- Added `release:check` task (no arguments)
|
|
133
|
+
- Added `release:tag` task (uses `usage` field for version argument)
|
|
134
|
+
- Added `release:prepare` task (uses `usage` field for version argument)
|
|
135
|
+
|
|
136
|
+
### New Files
|
|
137
|
+
1. `.github/workflows/PUBLISH_GUIDE.md`
|
|
138
|
+
- Complete publishing guide
|
|
139
|
+
- OIDC setup instructions
|
|
140
|
+
- Step-by-step release process
|
|
141
|
+
- Troubleshooting guide
|
|
142
|
+
|
|
143
|
+
2. `.github/workflows/IMPROVEMENTS.md`
|
|
144
|
+
- Critical analysis of workflow
|
|
145
|
+
- Improvement recommendations
|
|
146
|
+
- Security guardrails documentation
|
|
147
|
+
|
|
148
|
+
3. `.github/RELEASE_CHECKLIST.md`
|
|
149
|
+
- Pre-release checklist
|
|
150
|
+
- Release process steps
|
|
151
|
+
- Post-release verification
|
|
152
|
+
- Emergency rollback procedure
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Security Guardrails Implemented
|
|
157
|
+
|
|
158
|
+
### 1. Environment Protection
|
|
159
|
+
- `pypi` environment requires manual approval
|
|
160
|
+
- Only `main` branch can deploy to production
|
|
161
|
+
- `test.pypi` has no protection (dev deployments)
|
|
162
|
+
|
|
163
|
+
### 2. Workflow Conditions
|
|
164
|
+
```yaml
|
|
165
|
+
publish-release:
|
|
166
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
|
167
|
+
```
|
|
168
|
+
- Only tag pushes trigger production releases
|
|
169
|
+
- Regular commits only publish to Test PyPI
|
|
170
|
+
|
|
171
|
+
### 3. OIDC Authentication
|
|
172
|
+
- No long-lived secrets
|
|
173
|
+
- Short-lived tokens (15 min max)
|
|
174
|
+
- Bound to specific repo/workflow/environment
|
|
175
|
+
|
|
176
|
+
### 4. Version Validation
|
|
177
|
+
```bash
|
|
178
|
+
if ! echo "$TAG_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
179
|
+
echo "ERROR: Version must follow semantic versioning"
|
|
180
|
+
exit 1
|
|
181
|
+
fi
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### 5. Pre-release Checks
|
|
185
|
+
```bash
|
|
186
|
+
mise run release:check # Runs linter + tests + build
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### 6. Concurrency Control
|
|
190
|
+
```yaml
|
|
191
|
+
concurrency:
|
|
192
|
+
group: release-${{ github.sha }}
|
|
193
|
+
cancel-in-progress: false # Never cancel production releases
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
198
|
+
## Step-by-Step Production Release
|
|
199
|
+
|
|
200
|
+
### Prerequisites (One-time)
|
|
201
|
+
|
|
202
|
+
1. **Configure PyPI Trusted Publisher**:
|
|
203
|
+
- Go to: https://pypi.org/manage/project/openwebui-mcp-server/settings/publishing/
|
|
204
|
+
- Add trusted publisher:
|
|
205
|
+
- Owner: `stephanschielke`
|
|
206
|
+
- Repository: `open-webui-mcp-server`
|
|
207
|
+
- Workflow: `publish.yml`
|
|
208
|
+
- Environment: `pypi`
|
|
209
|
+
|
|
210
|
+
2. **Verify GitHub Environment**:
|
|
211
|
+
- Go to: https://github.com/stephanschielke/open-webui-mcp-server/settings/environments
|
|
212
|
+
- Ensure `pypi` environment has:
|
|
213
|
+
- Required reviewers: At least one maintainer
|
|
214
|
+
- Deployment branches: Only `main`
|
|
215
|
+
|
|
216
|
+
### Release Process
|
|
217
|
+
|
|
218
|
+
#### Step 1: Prepare Release (Local)
|
|
219
|
+
```bash
|
|
220
|
+
git checkout main
|
|
221
|
+
git pull origin main
|
|
222
|
+
mise run release:check
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
#### Step 2: Create Release
|
|
226
|
+
```bash
|
|
227
|
+
# Option A: Automated (recommended)
|
|
228
|
+
mise run release:prepare 0.2.0
|
|
229
|
+
|
|
230
|
+
# Option B: Manual
|
|
231
|
+
mise run bump:patch
|
|
232
|
+
git add pyproject.toml
|
|
233
|
+
git commit -m "chore: bump version to 0.2.0"
|
|
234
|
+
git tag -a v0.2.0 -m "Release v0.2.0"
|
|
235
|
+
git push origin main v0.2.0
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
#### Step 3: Monitor Release
|
|
239
|
+
1. Watch GitHub Actions: https://github.com/stephanschielke/open-webui-mcp-server/actions
|
|
240
|
+
2. Approve deployment when prompted
|
|
241
|
+
3. Verify PyPI upload: https://pypi.org/project/openwebui-mcp-server/
|
|
242
|
+
|
|
243
|
+
#### Step 4: Verify Installation
|
|
244
|
+
```bash
|
|
245
|
+
# Wait 5-10 minutes for PyPI CDN
|
|
246
|
+
pip install openwebui-mcp-server==0.2.0
|
|
247
|
+
openwebui-mcp --version
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Validation
|
|
253
|
+
|
|
254
|
+
All changes have been validated:
|
|
255
|
+
- ✅ `ghalint` linter passes
|
|
256
|
+
- ✅ `act --validate` passes
|
|
257
|
+
- ✅ Follows existing workflow patterns
|
|
258
|
+
- ✅ Matches mise.toml configuration
|
|
259
|
+
- ✅ OIDC authentication implemented
|
|
260
|
+
- ✅ Security guardrails in place
|
|
261
|
+
- ✅ Mise tasks use proper `usage` field syntax
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## Next Steps
|
|
266
|
+
|
|
267
|
+
### Immediate Actions Required
|
|
268
|
+
1. Configure trusted publisher on PyPI.org
|
|
269
|
+
2. Test OIDC with a release
|
|
270
|
+
3. Remove `PYPI_ACCOUNT_API_TOKEN` after verification
|
|
271
|
+
|
|
272
|
+
### Optional Improvements
|
|
273
|
+
1. Add changelog generation (git-cliff or similar)
|
|
274
|
+
2. Add release notes automation
|
|
275
|
+
3. Add pre-release support (alpha/beta/rc)
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
## References
|
|
280
|
+
|
|
281
|
+
- [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
|
|
282
|
+
- [GitHub Actions OIDC](https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-pypi)
|
|
283
|
+
- [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish)
|
|
284
|
+
- [Mise Task Arguments](https://mise.jdx.dev/tasks/task-arguments.html)
|
|
285
|
+
- [Semantic Versioning](https://semver.org/)
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
**The production publishing workflow is now complete with OIDC authentication, comprehensive guardrails, proper mise task syntax, and full documentation.**
|
|
@@ -0,0 +1,289 @@
|
|
|
1
|
+
# Workflow Improvements and Critical Analysis
|
|
2
|
+
|
|
3
|
+
This document addresses critical questions about the production publishing workflow and provides a comprehensive improvement plan.
|
|
4
|
+
|
|
5
|
+
## Critical Questions Answered
|
|
6
|
+
|
|
7
|
+
### 1. Tag Creation: Who creates `v*` tags?
|
|
8
|
+
|
|
9
|
+
**Answer**: Manual tag creation by maintainers (currently).
|
|
10
|
+
|
|
11
|
+
**Recommendation**: Add automated tag creation via mise tasks.
|
|
12
|
+
|
|
13
|
+
**Implementation**:
|
|
14
|
+
```bash
|
|
15
|
+
# New mise tasks added:
|
|
16
|
+
mise run release:prepare 0.2.0 # Runs checks, bumps version, creates tag
|
|
17
|
+
mise run release:tag 0.2.0 # Just creates the tag
|
|
18
|
+
mise run release:check # Just runs pre-release checks
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**When to create tags**:
|
|
22
|
+
- After all PRs for a release are merged to main
|
|
23
|
+
- After running `mise run release:check` successfully
|
|
24
|
+
- When you're ready to publish to production PyPI
|
|
25
|
+
|
|
26
|
+
**Guardrails**:
|
|
27
|
+
- Pre-release checks must pass
|
|
28
|
+
- No uncommitted changes
|
|
29
|
+
- Semantic versioning enforced
|
|
30
|
+
- Tag existence check
|
|
31
|
+
|
|
32
|
+
---
|
|
33
|
+
|
|
34
|
+
### 2. Artifact Visibility: Can we see artifacts?
|
|
35
|
+
|
|
36
|
+
**Answer**: Yes, artifacts are visible in GitHub Actions UI.
|
|
37
|
+
|
|
38
|
+
**Where to find them**:
|
|
39
|
+
1. Go to any workflow run: https://github.com/stephanschielke/open-webui-mcp-server/actions
|
|
40
|
+
2. Click on a completed workflow run
|
|
41
|
+
3. Scroll to "Artifacts" section at the bottom
|
|
42
|
+
4. Download `python-package-distributions`
|
|
43
|
+
|
|
44
|
+
**Artifact contents**:
|
|
45
|
+
- `dist/*.whl` - Built wheel distribution
|
|
46
|
+
- `dist/*.tar.gz` - Source distribution
|
|
47
|
+
|
|
48
|
+
**Retention**:
|
|
49
|
+
- Remote GitHub: 5 days
|
|
50
|
+
- Local act: 1 day
|
|
51
|
+
|
|
52
|
+
**Note**: Artifacts are only available for completed workflow runs. If a workflow is cancelled or fails, artifacts may not be available.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### 3. ghalint: Should it be a job or step?
|
|
57
|
+
|
|
58
|
+
**Answer**: It's now a step in the build job.
|
|
59
|
+
|
|
60
|
+
**Implementation**:
|
|
61
|
+
```yaml
|
|
62
|
+
- name: Validate workflow
|
|
63
|
+
run: mise run owu:gha:lint
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Why as a step**:
|
|
67
|
+
- Catches workflow issues early
|
|
68
|
+
- No separate job overhead
|
|
69
|
+
- Fails fast if workflow has security issues
|
|
70
|
+
- Runs on every push
|
|
71
|
+
|
|
72
|
+
**Alternative**: Could be a separate job if you want to:
|
|
73
|
+
- Run it in parallel with build
|
|
74
|
+
- Have clearer separation of concerns
|
|
75
|
+
- Skip it in certain conditions
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 4. Rebuild: Do we need to rebuild with artifacts?
|
|
80
|
+
|
|
81
|
+
**Answer**: Yes, but only for production releases.
|
|
82
|
+
|
|
83
|
+
**Why we rebuild**:
|
|
84
|
+
1. The artifact from `build` job has the dev version (e.g., `0.2.0.dev1`)
|
|
85
|
+
2. For production, we need the release version (e.g., `0.2.0`)
|
|
86
|
+
3. We set the version from the tag, then rebuild
|
|
87
|
+
|
|
88
|
+
**Flow**:
|
|
89
|
+
```
|
|
90
|
+
build job → artifact (0.2.0.dev1)
|
|
91
|
+
↓
|
|
92
|
+
publish-release job → download artifact → set version (0.2.0) → rebuild → publish
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
**Optimization opportunity**: We could build with the release version from the start if we detect a tag push. But this would complicate the build job logic.
|
|
96
|
+
|
|
97
|
+
**Current approach is correct** because:
|
|
98
|
+
- Build job runs on every push (needs dev version)
|
|
99
|
+
- Release job only runs on tags (needs release version)
|
|
100
|
+
- Rebuilding ensures correct version in package
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
### 5. OIDC vs API Token: Should we use OIDC?
|
|
105
|
+
|
|
106
|
+
**Answer**: Yes! OIDC is implemented.
|
|
107
|
+
|
|
108
|
+
**Current state**:
|
|
109
|
+
- Test PyPI: Already using OIDC (trusted publishing configured)
|
|
110
|
+
- Production PyPI: Now using OIDC (workflow updated)
|
|
111
|
+
|
|
112
|
+
**Migration path**:
|
|
113
|
+
1. ✅ Configure trusted publisher on PyPI
|
|
114
|
+
2. ✅ Update workflow to use OIDC (no credentials)
|
|
115
|
+
3. ⏳ Test with a release
|
|
116
|
+
4. ⏳ Remove `PYPI_ACCOUNT_API_TOKEN` secret after verification
|
|
117
|
+
|
|
118
|
+
**Security benefits**:
|
|
119
|
+
|
|
120
|
+
| Aspect | API Token | OIDC |
|
|
121
|
+
|-----------------|--------------|----------------|
|
|
122
|
+
| Lifespan | Months/years | 15 minutes max |
|
|
123
|
+
| Secret required | Yes | No |
|
|
124
|
+
| Rotation | Manual | Automatic |
|
|
125
|
+
| Leak risk | High | Low |
|
|
126
|
+
| Audit trail | Limited | Full |
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Implementation Checklist
|
|
131
|
+
|
|
132
|
+
### Completed
|
|
133
|
+
- [x] Add ghalint validation to build job
|
|
134
|
+
- [x] Implement OIDC for production PyPI
|
|
135
|
+
- [x] Add version validation in publish-release job
|
|
136
|
+
- [x] Create GitHub Release job with changelog
|
|
137
|
+
- [x] Add mise tasks for release management
|
|
138
|
+
- [x] Create PUBLISH_GUIDE.md
|
|
139
|
+
- [x] Create RELEASE_CHECKLIST.md
|
|
140
|
+
- [x] Fix ghalint persist-credentials warning
|
|
141
|
+
|
|
142
|
+
### Pending (Requires Manual Action)
|
|
143
|
+
- [ ] Configure trusted publisher on PyPI.org
|
|
144
|
+
- [ ] Test OIDC with a release
|
|
145
|
+
- [ ] Remove `PYPI_ACCOUNT_API_TOKEN` after verification
|
|
146
|
+
- [ ] Add branch protection rules (if not already done)
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Security Guardrails Implemented
|
|
151
|
+
|
|
152
|
+
### 1. Environment Protection
|
|
153
|
+
- `pypi` environment requires manual approval
|
|
154
|
+
- Only `main` branch can deploy to production
|
|
155
|
+
- `test.pypi` has no protection (dev deployments)
|
|
156
|
+
|
|
157
|
+
### 2. Workflow Conditions
|
|
158
|
+
```yaml
|
|
159
|
+
publish-release:
|
|
160
|
+
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
|
161
|
+
```
|
|
162
|
+
- Only tag pushes trigger production releases
|
|
163
|
+
- Regular commits only publish to Test PyPI
|
|
164
|
+
|
|
165
|
+
### 3. OIDC Authentication
|
|
166
|
+
- No long-lived secrets
|
|
167
|
+
- Short-lived tokens (15 min max)
|
|
168
|
+
- Bound to specific repo/workflow/environment
|
|
169
|
+
|
|
170
|
+
### 4. Version Validation
|
|
171
|
+
```bash
|
|
172
|
+
if ! echo "$TAG_VERSION" | grep -qE '^[0-9]+\.[0-9]+\.[0-9]+$'; then
|
|
173
|
+
echo "ERROR: Version must follow semantic versioning"
|
|
174
|
+
exit 1
|
|
175
|
+
fi
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
### 5. Pre-release Checks
|
|
179
|
+
```bash
|
|
180
|
+
mise run release:check # Runs linter + tests + build
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 6. Concurrency Control
|
|
184
|
+
```yaml
|
|
185
|
+
concurrency:
|
|
186
|
+
group: release-${{ github.sha }}
|
|
187
|
+
cancel-in-progress: false # Never cancel production releases
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
---
|
|
191
|
+
|
|
192
|
+
## Step-by-Step Production Release Guide
|
|
193
|
+
|
|
194
|
+
### Prerequisites (One-time Setup)
|
|
195
|
+
|
|
196
|
+
1. **Configure PyPI Trusted Publisher**:
|
|
197
|
+
- Go to: https://pypi.org/manage/project/openwebui-mcp-server/settings/publishing/
|
|
198
|
+
- Add trusted publisher:
|
|
199
|
+
- Owner: `stephanschielke`
|
|
200
|
+
- Repository: `open-webui-mcp-server`
|
|
201
|
+
- Workflow: `publish.yml`
|
|
202
|
+
- Environment: `pypi`
|
|
203
|
+
|
|
204
|
+
2. **Verify GitHub Environment**:
|
|
205
|
+
- Go to: https://github.com/stephanschielke/open-webui-mcp-server/settings/environments
|
|
206
|
+
- Ensure `pypi` environment has:
|
|
207
|
+
- Required reviewers: At least one maintainer
|
|
208
|
+
- Deployment branches: Only `main`
|
|
209
|
+
|
|
210
|
+
### Release Process
|
|
211
|
+
|
|
212
|
+
#### Step 1: Prepare Release (Local)
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# Ensure you're on main and up to date
|
|
216
|
+
git checkout main
|
|
217
|
+
git pull origin main
|
|
218
|
+
|
|
219
|
+
# Run pre-release checks
|
|
220
|
+
mise run release:check
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
#### Step 2: Create Release
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
# Option A: Automated (recommended)
|
|
227
|
+
mise run release:prepare 0.2.0
|
|
228
|
+
|
|
229
|
+
# Option B: Manual
|
|
230
|
+
mise run bump:patch
|
|
231
|
+
git add pyproject.toml
|
|
232
|
+
git commit -m "chore: bump version to 0.2.0"
|
|
233
|
+
git tag -a v0.2.0 -m "Release v0.2.0"
|
|
234
|
+
git push origin main v0.2.0
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
#### Step 3: Monitor Release
|
|
238
|
+
|
|
239
|
+
1. Watch GitHub Actions: https://github.com/stephanschielke/open-webui-mcp-server/actions
|
|
240
|
+
2. Approve deployment when prompted
|
|
241
|
+
3. Verify PyPI upload: https://pypi.org/project/openwebui-mcp-server/
|
|
242
|
+
|
|
243
|
+
#### Step 4: Verify Installation
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
# Wait 5-10 minutes for PyPI CDN
|
|
247
|
+
pip install openwebui-mcp-server==0.2.0
|
|
248
|
+
openwebui-mcp --version
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## Troubleshooting
|
|
254
|
+
|
|
255
|
+
### Issue: "OIDC token request failed"
|
|
256
|
+
|
|
257
|
+
**Cause**: Trusted publisher not configured
|
|
258
|
+
|
|
259
|
+
**Solution**:
|
|
260
|
+
1. Verify trusted publisher settings on PyPI
|
|
261
|
+
2. Ensure workflow name matches exactly
|
|
262
|
+
3. Ensure environment name matches
|
|
263
|
+
|
|
264
|
+
### Issue: "Version already exists"
|
|
265
|
+
|
|
266
|
+
**Cause**: Trying to publish existing version
|
|
267
|
+
|
|
268
|
+
**Solution**:
|
|
269
|
+
1. Bump version in `pyproject.toml`
|
|
270
|
+
2. Create new tag
|
|
271
|
+
3. Never reuse version numbers
|
|
272
|
+
|
|
273
|
+
### Issue: "Environment protection failed"
|
|
274
|
+
|
|
275
|
+
**Cause**: Deployment blocked
|
|
276
|
+
|
|
277
|
+
**Solution**:
|
|
278
|
+
1. Check if you're a required reviewer
|
|
279
|
+
2. Approve deployment in Actions UI
|
|
280
|
+
3. Verify deploying from `main` branch
|
|
281
|
+
|
|
282
|
+
---
|
|
283
|
+
|
|
284
|
+
## References
|
|
285
|
+
|
|
286
|
+
- [PyPI Trusted Publishing](https://docs.pypi.org/trusted-publishers/)
|
|
287
|
+
- [GitHub Actions OIDC](https://docs.github.com/actions/deployment/security-hardening-your-deployments/configuring-openid-connect-in-pypi)
|
|
288
|
+
- [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish)
|
|
289
|
+
- [Semantic Versioning](https://semver.org/)
|