Merge pull request #637 from AIOSAI/dev

security(ci): least-privilege token on e2e-wheel workflow + W24 changelog (also carries playbook commit 6b89fcd)
This commit is contained in:
AIPass
2026-06-08 10:36:14 -07:00
committed by GitHub
6 changed files with 50 additions and 6 deletions
+5
View File
@@ -23,6 +23,11 @@ on:
- "src/**"
workflow_dispatch:
# Least-privilege token (Scorecard Token-Permissions). This workflow only
# reads the repo to build + smoke-test the wheel; it needs no write scopes.
permissions:
contents: read
jobs:
e2e-wheel:
name: e2e-wheel (${{ matrix.os }})
+12
View File
@@ -41,12 +41,24 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: write
id-token: write # keyless Sigstore signing (OIDC); no signing key exists
steps:
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: dist
path: dist/
- name: Sign artifacts with Sigstore (keyless, OIDC)
# Produces dist/<artifact>.sigstore.json bundles next to each wheel/sdist.
# The 'gh release create dist/*' step below then attaches them to the
# GitHub Release, which is where Scorecard's Signed-Releases check looks.
# release-signing-artifacts is disabled: the action's own auto-attach only
# fires on a 'release: published' event, but we trigger on 'push: tags',
# so we upload the bundles ourselves via the dist/* glob.
uses: sigstore/gh-action-sigstore-python@04cffa1d795717b140764e8b640de88853c92acc # v3.3.0
with:
inputs: ./dist/*.tar.gz ./dist/*.whl
release-signing-artifacts: false
- name: Extract latest CHANGELOG section
run: |
# Grab the topmost "## [...]" block from CHANGELOG.md as release notes.
+20
View File
@@ -8,6 +8,26 @@ and this project uses [Calendar Versioning](https://calver.org/) in the format
---
## [2026.W24] - 2026-06-08
### Security
- **Least-privilege token on the `e2e-wheel` workflow.** `e2e-wheel.yml` was the
one CI workflow missing a top-level `permissions:` block (it was added during
the cross-OS work after PR #624 hardened the others), so it ran with the
default broad `GITHUB_TOKEN` scopes — dropping the OpenSSF Scorecard
Token-Permissions check to 0. Added `permissions: contents: read`; the
workflow only reads the repo to build and smoke-test the wheel.
- **Signed GitHub Releases via Sigstore (keyless).** The release workflow now
signs the built wheel + sdist with `sigstore/gh-action-sigstore-python`
(keyless OIDC — no signing key is generated, stored, or held by anyone) and
attaches the resulting `.sigstore.json` bundles to the GitHub Release. PyPI
uploads were already attested via Trusted Publishing; this extends verifiable
provenance to artifacts pulled from GitHub Releases and satisfies the OpenSSF
Scorecard Signed-Releases check. First proof lands on the next `v*` tag.
---
## [2026.W23] - 2026-06-02
### Fixed
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "aipass"
version = "2.5.1"
version = "2.5.2"
description = "A local multi-agent framework where your AI agents keep their memory, work together, and never ask you to re-explain context"
readme = "README.md"
license = "MIT"
+1 -1
View File
@@ -4,4 +4,4 @@ pip install aipass
https://github.com/AIOSAI/AIPass
"""
__version__ = "2.5.1"
__version__ = "2.5.2"
@@ -26,7 +26,8 @@ the vectorized trail. Close when done.
- [ ] On `dev`, working tree understood: `drone @git status --all`
- [ ] Confirm what's shipping this week — scan uncommitted changes + already-pushed dev commits ahead of main: `git rev-list --count main..dev` (read git, raw ok)
- [ ] No surprise files (stray `/tmp` artifacts, test pollution, `.recovery`/`.archive` churn). Clean = archive, never delete.
- [ ] Decide: **release tag this week?** (tag = PyPI publish + GitHub Release). If yes, note target version.
- [ ] **Version state check** (informs the bump decision): read the **two** release-tied versions — `grep '^version' pyproject.toml` and `grep __version__ src/aipass/__init__.py` (they should match; if drifted, note it) — and what PyPI already has: `curl -s https://pypi.org/pypi/aipass/json | python3 -c "import sys,json;print(json.load(sys.stdin)['info']['version'])"`. PyPI rejects a duplicate, so the target must be > published.
- [ ] Decide: **release tag this week?** (tag = PyPI publish + GitHub Release). If yes, note target version. (Significance call is the user's — the PATCH-default rule below is guidance, and the actual release history is a useful tie-breaker.)
## 2. Verify, commit, CHANGELOG
@@ -56,6 +57,7 @@ The PR gate (verified against `.github/workflows/`):
- [ ] **User's call to merge** — confirm GO
- [ ] `drone @git merge <PR#>` (squash-merge)
- [ ] ⚠️ The merge command **echoes the PR's ORIGINAL opening description** — often stale if the PR accumulated more work after it was opened. Don't trust it as the merge summary; the real contents are `git log main..dev` from before the merge.
- [ ] ⚠️ **Verify `dev` SURVIVES the merge** (the #625 scar — empirical, every time): `drone @git branches` → `dev` still present; `git rev-parse dev` resolves
## 6. Post-merge realign
@@ -80,10 +82,15 @@ How the release fires (verified `publish.yml`): a `v*` **git tag push** runs bui
- GitHub Release notes = the **topmost `## [...]` CHANGELOG block** (awk-extracted).
Steps:
- [ ] Bump `pyproject.toml` version per the rule above, **on dev so it rides into the PR** (then main's merge commit carries the right version)
- [ ] Bump the version in **BOTH** files (they must match the tag, or `__version__` ships wrong): `pyproject.toml` `version` **and** `src/aipass/__init__.py` `__version__`. Do it **on dev so it rides into the PR** (then main's merge commit carries the right version). ⚠️ These two drift easily — `__init__.py` is the one that gets forgotten.
- [ ] Confirm the CHANGELOG top section is the release notes you want
- [ ] **Push the tag — MANUAL (drone has no `tag` verb):** Patrick, or raw `git tag v<version> <main-sha>` + `git push origin v<version>` via `!`, on the merged main commit
- [ ] Verify PyPI shows the new version + the GitHub Release appeared
- [ ] After merge + `drone @git sync`, get the **real** merged-main sha: `git rev-parse HEAD`. **Verify the version on that exact commit BEFORE tagging:** `git show HEAD:pyproject.toml | grep '^version'` and `git show HEAD:src/aipass/__init__.py | grep __version__` — both must equal the tag.
- [ ] **Push the tag — MANUAL (drone has no `tag` verb; devpulse can't push tags):** user runs it, via `!` or terminal. **Two SEPARATE lines, paste the real sha (no `<…>` placeholders, no `&&`):**
```
git tag v<version> <real-sha-from-rev-parse>
git push origin v<version>
```
- [ ] Verify PyPI shows the new version + the GitHub Release appeared (`curl -s https://pypi.org/pypi/aipass/json | python3 -c "import sys,json;print(json.load(sys.stdin)['info']['version'])"`)
- [ ] Record the tag → Run Summary
## 8. Wrap