Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
- `scripts/check_versions.py`: version touch points, stale previous-version mentions, release-notes presence, draft-first workflow lint.
- `scripts/verify_release.py`: downloaded assets vs SHA256SUMS, GitHub digests and the local candidate.
- Independent review fixes (2026-10-08): identical archives on Windows and Linux (`create_system` pinned, LF-only `.gitattributes`, CI `same-bytes` job); workflow lint judges each `gh release create`; version patterns no longer match prefixes (1.2.1 vs 1.2.10); host invariants enforced regardless of config; Opal rejects multi-line descriptions; draft metadata fetched from the releases list; `--expect-published` / `--expect-immutable`; CI runs the gate checks and Python 3.8; checkout without persisted credentials.
- Pilot lessons (folder-cleanup v1.6.2, 2026-10-08): where release actions run — tag push, draft publish and settings changes may be refused from cloud sessions and move to the owner's machine; passkey/sudo-mode stop-and-ask; REST per-asset download fallback when `gh release download` (GraphQL) is blocked.
- Dated host matrix (Claude app, Claude Code, Codex/ChatGPT, Microsoft Copilot, Grok, Gemini Apps, Opal, Antigravity, local models).
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# GitHub Release

By **[Jesse Raber](https://jesseraber.net)** — owner of Unique WoodWorx and builder of practical AI workflows for real-world businesses. [Consulting](https://jesseraber.net) · [YouTube](https://www.youtube.com/@Jesse_Raber)

An Agent Skill that teaches AI agents to set up skill repositories and release them right the first time: a version gate before any tag, deterministic packages for each AI host, draft-first publishing, verification that published bytes equal the tested build, and a dated per-host install log.

## Which ZIP do I download?
Expand All @@ -24,4 +26,8 @@ An Agent Skill that teaches AI agents to set up skill repositories and release t

`skills/github-release/` is the skill. `packaging/` builds and checks releases of this repository with the skill's own templates.

## About the author

I'm Jesse Raber, owner of [Unique WoodWorx](https://uniquewoodworx.com), a custom cabinet shop in Odon, Indiana. I built this skill because my own AI-driven releases kept going wrong in ways the agents couldn't see. If you want help putting AI agents to work in your business — CNC, cabinet software, or workflows like this one — that's what I do at [jesseraber.net](https://jesseraber.net). Build and release walkthroughs: [YouTube](https://www.youtube.com/@Jesse_Raber).

MIT licensed.
3 changes: 3 additions & 0 deletions packaging/RELEASE_NOTES_v0.1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,6 @@ Verify downloads with `sha256sum -c SHA256SUMS.txt`.
## Publication boundary

Installed host copies are updated separately; this release does not change any host by itself.

---
Built by [Jesse Raber](https://jesseraber.net) · [YouTube](https://www.youtube.com/@Jesse_Raber)
23 changes: 20 additions & 3 deletions skills/github-release/references/publish.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,19 @@ Not included: publishing the draft, repository settings, host installs

An approval covers only what the block lists.

## 2. Where pushes run
## 2. Where release actions run

Observed 2026-10-08 (multi-agent-folder-cleanup v1.6.2 pilot): a cloud agent session could not create tags (git push dropped by the proxy; REST tag create 403), could not publish a draft (403 "editing releases not permitted"), and could not change repository settings. Expect the same split and say so before starting:

| Action | Cloud agent session | Owner's machine |
|---|---|---|
| Build candidate, gate, open/merge PRs, read releases | usually works | works |
| Push the tag | may be refused (observed) | signed-in `git` in a fresh temp clone, `core.autocrlf=false` |
| Publish the draft (`gh release edit --draft=false`) | may be refused (observed) | signed-in `gh` |
| Repository settings (branch protection, immutable releases) | refused (observed) | owner's browser or `gh`; may require the owner's **passkey ("sudo mode")** — the agent must stop and ask the owner to complete it; never ask for the credential |

When a step is refused from the cloud, do not retry through another route; hand the owner the exact command and wait. The refusal changes where the step runs, never the approval for it.

- A cloud connector may not be able to create tags (observed). Push from the owner's machine with their signed-in `git`/`gh`, in a fresh temporary clone with `core.autocrlf=false`.
- Typical flow: feature PR (CI green) → merge → release PR with version bump (CI green) → merge → annotated tag on the merge commit.

```bash
Expand All @@ -32,7 +42,12 @@ git push origin v1.2.0
## 3. Draft created → verify

1. Wait for the workflow. Confirm the release is a **draft** (`gh release view v1.2.0 --json isDraft`).
2. Download every asset: `gh release download v1.2.0 --dir ../draft-1.2.0` (drafts need an authenticated `gh`).
2. Download every asset: `gh release download v1.2.0 --dir ../draft-1.2.0` (drafts need an authenticated `gh`). `gh release download` uses GraphQL, which some proxies block (observed); fall back to REST per asset:

```bash
gh api repos/<owner>/<repo>/releases --jq '.[] | select(.tag_name=="v1.2.0") | .assets[] | [.id, .name] | @tsv'
gh api -H "Accept: application/octet-stream" repos/<owner>/<repo>/releases/assets/<id> > ../draft-1.2.0/<name>
```
3. Save the draft's metadata. The `releases/tags/` endpoint returns published releases only, so select the draft from the list:
`gh api repos/<owner>/<repo>/releases --jq '.[] | select(.tag_name=="v1.2.0")' > ../draft-1.2.0.json`
4. Run:
Expand All @@ -54,6 +69,8 @@ Second approval block: version, asset list with hashes, verify result. On yes:
gh release edit v1.2.0 --draft=false
```

If the session's publish call is refused (observed from cloud: 403), the owner runs this exact command on their machine; the approval already given covers it unchanged.

With immutable releases enabled in repository settings, assets and the tag are locked from this moment (documented behavior; confirm on the first release). Any later defect becomes a new patch version.

## 5. After publishing
Expand Down
2 changes: 1 addition & 1 deletion skills/github-release/references/repo-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ Use in **Setup**. Draft everything locally first; creating the GitHub repository
1. Owner reviews the local draft repository.
2. Create the repository (approval: name, visibility, owner account).
3. Push `main` (approval).
4. Settings: branch protection, immutable releases (approval).
4. Settings: branch protection, immutable releases (approval). Settings changes are usually refused from cloud agent sessions (observed 2026-10-08) and run in the owner's browser or signed-in `gh`; GitHub may demand the owner's passkey ("sudo mode") — stop and ask the owner to complete it, then confirm the result by API read (for example `gh api repos/<owner>/<repo>/branches/main/protection`).
5. First release follows publish.md.
Loading