Compare commits
3
Commits
6d54c1e96c
...
56e3456cfc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
56e3456cfc | ||
|
|
0208c67e59 | ||
|
|
6bb2288470 |
@@ -198,6 +198,87 @@ jobs:
|
|||||||
git push origin HEAD:main
|
git push origin HEAD:main
|
||||||
echo "homebrew: tap updated to rdbms-playground $VER."
|
echo "homebrew: tap updated to rdbms-playground $VER."
|
||||||
|
|
||||||
# winget remains a future sibling job here (komac on Linux CI, or a manual PR
|
# Update the winget package (Windows) by opening a PR to microsoft/winget-pkgs
|
||||||
# to microsoft/winget-pkgs). No `needs:` between jobs — each is independent and
|
# with komac. Unlike scoop-bucket/homebrew-tap (which push to OUR repos and are
|
||||||
# idempotent, so one failing or being added never breaks another.
|
# live at once), winget is a PR into Microsoft's central, human-gated catalog —
|
||||||
|
# asynchronous, and re-submitting the same version would open a DUPLICATE PR. So
|
||||||
|
# this job guards on both already-merged versions AND already-open PRs before
|
||||||
|
# submitting, which keeps a repeated `publish` dispatch safe.
|
||||||
|
#
|
||||||
|
# Auth: komac needs a CLASSIC GitHub PAT with `public_repo` (fine-grained tokens
|
||||||
|
# cannot open the cross-fork PR — komac #310). It is held on a dedicated GitHub
|
||||||
|
# bot account (a leak can't reach other repos — same reasoning as lazyeval-ci)
|
||||||
|
# and referenced ONLY in this job's env (job-level secret scoping keeps it out
|
||||||
|
# of the other publish jobs).
|
||||||
|
#
|
||||||
|
# PREREQUISITE: the package `LazyEvaluation.RdbmsPlayground` must already exist
|
||||||
|
# in winget-pkgs via a one-time `komac new` (interactive — run manually once;
|
||||||
|
# see ADR-0056 Amendment 4). This job only does the per-release `komac update`.
|
||||||
|
winget:
|
||||||
|
runs-on: ci-public
|
||||||
|
container:
|
||||||
|
image: git.lazyeval.net/oli/rdbms-playground-ci:latest
|
||||||
|
steps:
|
||||||
|
- name: submit the winget update PR (idempotent)
|
||||||
|
shell: bash
|
||||||
|
env:
|
||||||
|
TAG: ${{ inputs.tag }}
|
||||||
|
# Classic public_repo PAT for the winget bot account. komac reads it
|
||||||
|
# from GITHUB_TOKEN; the API guards below read it via a curl config file
|
||||||
|
# so the token never appears in a command line / process list.
|
||||||
|
GITHUB_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }}
|
||||||
|
run: |
|
||||||
|
set -euo pipefail
|
||||||
|
VER="${TAG#v}"
|
||||||
|
PKG="LazyEvaluation.RdbmsPlayground"
|
||||||
|
echo "winget: targeting $PKG $VER ($TAG)"
|
||||||
|
|
||||||
|
# Auth header in a 0600 curl config (keeps the token out of argv/logs).
|
||||||
|
umask 077
|
||||||
|
printf 'header = "Authorization: Bearer %s"\nheader = "Accept: application/vnd.github+json"\n' \
|
||||||
|
"$GITHUB_TOKEN" > /tmp/gh-curlrc
|
||||||
|
api="https://api.github.com"
|
||||||
|
|
||||||
|
# Guard 1 — already merged into winget-pkgs?
|
||||||
|
# (manifests/<first-letter>/<Publisher>/<Package>/<version>)
|
||||||
|
merged=$(curl -sS -o /dev/null -w '%{http_code}' --config /tmp/gh-curlrc \
|
||||||
|
"$api/repos/microsoft/winget-pkgs/contents/manifests/l/LazyEvaluation/RdbmsPlayground/$VER" || echo 000)
|
||||||
|
if [ "$merged" = "200" ]; then
|
||||||
|
echo "winget: $PKG $VER already in winget-pkgs — nothing to do."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Guard 2 — an open PR for this exact id+version already? (avoid a dup)
|
||||||
|
# curl -G --data-urlencode does the URL-encoding (no jq in the image).
|
||||||
|
curl -sS -G --config /tmp/gh-curlrc \
|
||||||
|
--data-urlencode "q=repo:microsoft/winget-pkgs type:pr state:open in:title \"$PKG\" \"$VER\"" \
|
||||||
|
"$api/search/issues" -o /tmp/winget-search.json
|
||||||
|
open=$(node -e 'process.stdout.write(String(JSON.parse(require("fs").readFileSync("/tmp/winget-search.json","utf8")).total_count||0))')
|
||||||
|
if [ "$open" != "0" ]; then
|
||||||
|
echo "winget: an open PR for $PKG $VER already exists — skipping."
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install pinned komac (prebuilt glibc binary; the CI image has no
|
||||||
|
# cargo/komac). Pinned for reproducibility — bump deliberately.
|
||||||
|
KOMAC_VER=2.16.0
|
||||||
|
curl -fsSL -o /tmp/komac.tgz \
|
||||||
|
"https://github.com/russellbanks/Komac/releases/download/v$KOMAC_VER/komac-$KOMAC_VER-x86_64-unknown-linux-gnu.tar.gz"
|
||||||
|
tar -xzf /tmp/komac.tgz -C /tmp
|
||||||
|
komac_bin=$(find /tmp -maxdepth 2 -type f -name komac | head -1)
|
||||||
|
[ -n "$komac_bin" ] || { echo "ERROR: komac binary not found after extract" >&2; exit 1; }
|
||||||
|
|
||||||
|
base="https://git.lazyeval.net/oli/rdbms-playground/releases/download/$TAG"
|
||||||
|
echo "winget: submitting update PR via komac $KOMAC_VER"
|
||||||
|
# NB: confirm flags against `komac update --help` on first run — komac
|
||||||
|
# evolves; --version/--urls/--submit are the stable core. komac infers
|
||||||
|
# architecture + the `portable` installer type from the binaries.
|
||||||
|
"$komac_bin" update "$PKG" \
|
||||||
|
--version "$VER" \
|
||||||
|
--urls "$base/rdbms-playground-$TAG-x86_64-pc-windows-gnu.exe" \
|
||||||
|
"$base/rdbms-playground-$TAG-aarch64-pc-windows-gnullvm.exe" \
|
||||||
|
--submit
|
||||||
|
echo "winget: update PR submitted for $PKG $VER (Microsoft review is async)."
|
||||||
|
|
||||||
|
# No `needs:` between jobs — each is independent and idempotent, so one failing
|
||||||
|
# or being added never breaks another.
|
||||||
|
|||||||
@@ -176,3 +176,144 @@ whether macOS Gatekeeper accepts the **ad-hoc-signed** mac binary via
|
|||||||
requirement and `brew`'s curl download sets no quarantine xattr, unlike a
|
requirement and `brew`'s curl download sets no quarantine xattr, unlike a
|
||||||
browser download — but this rides on the still-parked Developer-ID signing
|
browser download — but this rides on the still-parked Developer-ID signing
|
||||||
decision). **Remaining D3:** winget (komac on Linux CI, or a manual PR).
|
decision). **Remaining D3:** winget (komac on Linux CI, or a manual PR).
|
||||||
|
|
||||||
|
## Amendment 3 — 2026-06-19: validated end-to-end; a presigned-URL/HEAD gotcha + the Caddy fix it needs
|
||||||
|
|
||||||
|
**Scoop and Homebrew now install and run end-to-end** (`v0.2.0`,
|
||||||
|
user-verified on real Windows + macOS): `scoop install rdbms-playground`
|
||||||
|
and `brew install lazyeval/tap/rdbms-playground` both fetch, checksum,
|
||||||
|
install, and the installed binary launches. Amendment 2's "unverified"
|
||||||
|
caveats are resolved (the `HEAD:main` push populated both repos cleanly).
|
||||||
|
|
||||||
|
**Distribution depends on a server-side Caddy rule — RECORD THIS: it lives
|
||||||
|
in the Gitea edge config, NOT this repo, and if it is lost in a server
|
||||||
|
rebuild Homebrew silently 403s again.** Symptom: `brew install` failed with
|
||||||
|
`curl (22) … 403` on the asset URL. Root cause: Gitea (≥1.25; here 1.26.2)
|
||||||
|
serves release-asset downloads by **303-redirecting to a method-bound
|
||||||
|
AWS-SigV4 presigned S3 URL** (OVH), signed for the *incoming* request's HTTP
|
||||||
|
verb. Homebrew **resolves the URL with a HEAD, captures the returned
|
||||||
|
(HEAD-signed) presigned URL, then runs the download GET against that
|
||||||
|
captured URL** → GET-on-a-HEAD-signed-URL → 403. Reproduced precisely:
|
||||||
|
`GET on HEAD-resolved = 403`, `HEAD on HEAD-resolved = 200`, `GET on
|
||||||
|
GET-resolved = 200`, `HEAD on GET-resolved = 403`. GET-only tools
|
||||||
|
(`install.sh`, `install.ps1`, `cargo binstall`, curl) are unaffected — they
|
||||||
|
GET the original URL and let it redirect fresh to a GET-signed URL. This is
|
||||||
|
a **Homebrew defect** (it reuses an ephemeral, method-scoped credential as
|
||||||
|
if it were a durable resource locator); Gitea's per-request method-bound
|
||||||
|
signing is correct, and SigV4 *cannot* sign one URL for two verbs.
|
||||||
|
`SERVE_DIRECT=false` (Gitea proxies, no presign) would also fix it but was
|
||||||
|
declined — not reshaping storage for one client.
|
||||||
|
|
||||||
|
**Fix (deployed, "Tier A"): a Caddy rule that answers HEAD on
|
||||||
|
release-download paths directly** — 200, no redirect, no body — so brew's
|
||||||
|
resolve records the *original* URL (no presigned credential captured) and
|
||||||
|
its download GET runs through the redirect fresh → GET-signed → 200. Scoped
|
||||||
|
to `method HEAD` + the release-download path; **GET is untouched**, so every
|
||||||
|
working channel is unaffected, and a HEAD carries no payload so no client
|
||||||
|
can *break* (at most a HEAD-probing download manager loses a progress-bar
|
||||||
|
size — cosmetic). Reference Caddyfile (place before the Gitea
|
||||||
|
reverse_proxy):
|
||||||
|
|
||||||
|
```
|
||||||
|
@release_head {
|
||||||
|
method HEAD
|
||||||
|
path_regexp ^/[^/]+/[^/]+/releases/download/.+
|
||||||
|
}
|
||||||
|
handle @release_head {
|
||||||
|
header Accept-Ranges bytes
|
||||||
|
header Content-Type application/octet-stream
|
||||||
|
respond 200
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
A "Tier B" variant (a sidecar that fetches and returns the *real*
|
||||||
|
Content-Length so even HEAD-probing clients stay fully faithful) was specced
|
||||||
|
but proved unnecessary — brew is happy with the bare 200.
|
||||||
|
|
||||||
|
**macOS signing:** the brew-installed binary **runs** under the current
|
||||||
|
**ad-hoc** signature (`codesign --sign -`) — confirmed on Apple Silicon.
|
||||||
|
**Developer-ID signing + notarization remains parked** pending the user's
|
||||||
|
Apple account conversion to an Organization (GA plan / ADR-ci-003); it is
|
||||||
|
needed for *browser-download* trust, not for the package-manager paths,
|
||||||
|
which are all working now.
|
||||||
|
|
||||||
|
**Remaining D3:** winget only.
|
||||||
|
|
||||||
|
## Amendment 4 — 2026-06-20: winget (D3 §3d) — the last package manager
|
||||||
|
|
||||||
|
winget wired as the fourth `publish.yaml` sibling job, **completing the D3
|
||||||
|
package-manager set** (crates.io/binstall, Scoop, Homebrew, winget; plus the
|
||||||
|
install scripts + direct binaries).
|
||||||
|
|
||||||
|
**Model — fundamentally unlike Scoop/Homebrew.** winget has no
|
||||||
|
self-hosted-source equivalent: its default catalog is the central,
|
||||||
|
**human-gated** GitHub repo `microsoft/winget-pkgs`, and you get in by
|
||||||
|
**opening a PR** of manifests into it. So the job submits a PR (via
|
||||||
|
**komac**, pinned `2.16.0`, prebuilt glibc binary — the CI image has no
|
||||||
|
cargo) and **Microsoft's pipeline validates async** (schema, SHA256,
|
||||||
|
AV/SmartScreen scan, sandbox install) + moderator review. It is *not* live
|
||||||
|
on dispatch like the bucket/tap.
|
||||||
|
|
||||||
|
**PackageIdentifier `LazyEvaluation.RdbmsPlayground`** (publisher segment =
|
||||||
|
the publishing entity / `lazyeval` org / license holder — consistent with
|
||||||
|
everything else). Bare-exe → winget **`portable`** installer type; x64
|
||||||
|
(`-pc-windows-gnu`) + arm64 (`-pc-windows-gnullvm`), komac infers arch +
|
||||||
|
type from the binaries.
|
||||||
|
|
||||||
|
**Auth — a dedicated GitHub bot, classic token.** komac needs a **classic
|
||||||
|
`public_repo` PAT**; **fine-grained tokens cannot open the cross-fork PR**
|
||||||
|
(komac #310 — the PR is created on the *target* repo you don't administer,
|
||||||
|
which the fine-grained model can't express). A classic `public_repo` token
|
||||||
|
can't be scoped to one repo, so it lives on a **dedicated GitHub bot
|
||||||
|
account** (a leak can't reach other repos — the lazyeval-ci reasoning), as
|
||||||
|
the `WINGET_GITHUB_TOKEN` secret, referenced **only** in the `winget` job
|
||||||
|
(job-level scoping keeps it away from the crates.io / lazyeval tokens) and
|
||||||
|
passed to the API guards via a 0600 curl config file (never argv).
|
||||||
|
|
||||||
|
**Idempotency — stronger than the others need.** A re-submitted version
|
||||||
|
would open a *duplicate* PR, so before submitting the job guards on **both**
|
||||||
|
(1) already-merged versions (`contents` API on
|
||||||
|
`manifests/l/LazyEvaluation/RdbmsPlayground/<ver>`) and (2) an already-open
|
||||||
|
PR for the id+version (`search/issues`). Either → clean skip, so a repeated
|
||||||
|
`publish` dispatch is safe even mid-review.
|
||||||
|
|
||||||
|
**Signing:** none required to *submit* (only MSIX needs it; ours is
|
||||||
|
portable). The unsigned binary may earn an AV/SmartScreen **manual-review
|
||||||
|
label** on the first PR — usually clears; a nudge toward Trusted Signing
|
||||||
|
(the UK Ltd clears the 3-year-history bar) but not a blocker. Continues the
|
||||||
|
parked Developer-ID/notarization posture.
|
||||||
|
|
||||||
|
**One-time bootstrap (manual — NOT in CI, because `komac new` is
|
||||||
|
interactive).** Run once to create the package in winget-pkgs, then CI
|
||||||
|
`komac update` handles every release after:
|
||||||
|
|
||||||
|
```
|
||||||
|
komac token update # paste the bot's classic public_repo PAT at the prompt (not in argv/history)
|
||||||
|
komac new LazyEvaluation.RdbmsPlayground \
|
||||||
|
-v 0.2.0 \
|
||||||
|
-u https://git.lazyeval.net/oli/rdbms-playground/releases/download/v0.2.0/rdbms-playground-v0.2.0-x86_64-pc-windows-gnu.exe \
|
||||||
|
https://git.lazyeval.net/oli/rdbms-playground/releases/download/v0.2.0/rdbms-playground-v0.2.0-aarch64-pc-windows-gnullvm.exe \
|
||||||
|
--publisher "Lazy Evaluation Ltd" --package-name "RDBMS Playground" \
|
||||||
|
--moniker rdbms-playground --license "MIT OR Apache-2.0" \
|
||||||
|
--package-url https://relplay.org -s
|
||||||
|
```
|
||||||
|
komac downloads the two exes, detects the bare binary as **`portable`**, and
|
||||||
|
**prompts for the command alias — enter `rdbms-playground`** so users get
|
||||||
|
that on PATH (not the long versioned filename). `-s` opens the PR; fill any
|
||||||
|
remaining prompts. (Flags verified against komac 2.16.0: `-v/--version`,
|
||||||
|
`-u/--urls`, `-s/--submit`; the alias has no flag and is prompted.) Once
|
||||||
|
that first PR merges, the CI job's `komac update` takes over.
|
||||||
|
|
||||||
|
**Bootstrap learnings (2026-06-21, first real run).** GitHub bot account =
|
||||||
|
`lazyeval-ci`. Its fork **`lazyeval-ci/winget-pkgs` must exist *before*
|
||||||
|
`komac new`** — komac's auto-fork races on winget-pkgs (one of GitHub's
|
||||||
|
largest repos) and fails with *"Could not resolve to a Repository
|
||||||
|
'lazyeval-ci/winget-pkgs'"*; fork it manually (web **Fork**, or `gh repo
|
||||||
|
fork microsoft/winget-pkgs --clone=false`), wait for it to populate, then
|
||||||
|
re-run. **Alias:** for a **direct single-exe portable**, winget derives the
|
||||||
|
on-PATH command from **`Commands[0]`** (the interactive "Commands" prompt →
|
||||||
|
`rdbms-playground`) — **not** `PortableCommandAlias`, which is
|
||||||
|
**archive/nested-portable-only** and must NOT be added to our manifest
|
||||||
|
(verified against winget-cli's portable-install logic + the 1.6.0 installer
|
||||||
|
schema; komac correctly omits it). So komac's generated manifest needs no
|
||||||
|
hand-editing. First PR: **#391335**.
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,145 @@
|
|||||||
|
# Session handoff — 2026-06-21 (75)
|
||||||
|
|
||||||
|
Continues from handoff-74 (v0.2.0 live on crates.io). This session **finished
|
||||||
|
the D3 package-manager rollout** — Scoop, Homebrew, and winget — plus the
|
||||||
|
Windows `install.ps1` fixes, and included a deep **presigned-URL / Homebrew**
|
||||||
|
debugging saga that's fixed by a server-side Caddy rule. Five commits; one
|
||||||
|
new ADR amendment arc (ADR-0056 Amendments 2–4).
|
||||||
|
|
||||||
|
## §1. State
|
||||||
|
|
||||||
|
**Branch `main`.** **No crate (Rust) code changed this session** — only
|
||||||
|
`.gitea/workflows/`, `scripts/`, and `docs/`. So the `cargo test` baseline
|
||||||
|
from handoff-74 (**2509 pass / 0 fail / 1 ignored**, clippy + `fmt --check`
|
||||||
|
clean) stands unchanged by construction; not re-run (nothing in the build
|
||||||
|
graph moved). New coverage this session is **`scripts/test-package-renders.sh`**
|
||||||
|
(shellcheck-clean, green), now gated on every push by a new **`ci.yaml`
|
||||||
|
`manifests` job** (bash + node; ruby-absent in CI degrades gracefully).
|
||||||
|
|
||||||
|
**Commits this session** (`cabc813`→`0208c67`; the workflow-bearing ones were
|
||||||
|
pushed, since the live `publish` dispatches + raw-URL installs the user tested
|
||||||
|
needed them on `main`):
|
||||||
|
- `42b40bc` install.ps1 → Windows PowerShell 5.1 compat
|
||||||
|
- `c0531aa` install.ps1 → immediate-use PATH + honest messaging
|
||||||
|
- `6d54c1e` Scoop + Homebrew jobs (D3 §3b/§3c)
|
||||||
|
- `6bb2288` Scoop/Homebrew validated + Caddy fix recorded (Amendment 3)
|
||||||
|
- `0208c67` winget job via komac (D3 §3d, Amendment 4)
|
||||||
|
|
||||||
|
**External / infra state created this session (NOT all in the repo):**
|
||||||
|
- **Caddy Tier-A HEAD rule on the Gitea server** — *load-bearing for Homebrew*,
|
||||||
|
lives in the Gitea edge config, **not** this repo (see §4). If lost on a
|
||||||
|
server rebuild, brew 403s again.
|
||||||
|
- **Gitea:** `lazyeval` org with repos **`scoop-bucket`** + **`homebrew-tap`**;
|
||||||
|
**`lazyeval-ci`** Gitea bot user (org team, Write to those repos);
|
||||||
|
**`LAZYEVAL_PKG_TOKEN`** secret on `oli/rdbms-playground`.
|
||||||
|
- **GitHub:** **`lazyeval-ci`** bot account; classic `public_repo` PAT →
|
||||||
|
**`WINGET_GITHUB_TOKEN`** secret on `oli/rdbms-playground`; fork
|
||||||
|
**`lazyeval-ci/winget-pkgs`**.
|
||||||
|
- **winget bootstrap PR [#391335](https://github.com/microsoft/winget-pkgs/pull/391335)**
|
||||||
|
submitted, in Microsoft review.
|
||||||
|
- **komac 2.16.0** installed locally at `~/.local/bin/komac`.
|
||||||
|
|
||||||
|
## §2. D3 — the package-manager set (the session's throughline)
|
||||||
|
|
||||||
|
| Channel | State |
|
||||||
|
| --- | --- |
|
||||||
|
| crates.io / `cargo binstall` | **live** (handoff-74) |
|
||||||
|
| `install.sh` / `install.ps1` | **live** — PS1 validated on ARM Windows 11 (5.1 + 7.6) |
|
||||||
|
| Scoop (`lazyeval/scoop-bucket`) | **live + validated** (install + run) |
|
||||||
|
| Homebrew (`lazyeval/homebrew-tap`) | **live + validated** — needs the Caddy rule (§4) |
|
||||||
|
| winget (`LazyEvaluation.RdbmsPlayground`) | **wired**; PR #391335 awaiting Microsoft merge |
|
||||||
|
|
||||||
|
How Scoop/Homebrew/winget are wired: sibling jobs in
|
||||||
|
`.gitea/workflows/publish.yaml` (manual `workflow_dispatch`, `tag` input),
|
||||||
|
each idempotent + independent. Scoop/Homebrew render **dependency-free bash**
|
||||||
|
manifests (`scripts/render-{scoop-manifest,homebrew-formula}.sh`) from the
|
||||||
|
release `.sha256` sidecars and push to the org repos via `LAZYEVAL_PKG_TOKEN`.
|
||||||
|
winget runs `komac update --submit` to PR `microsoft/winget-pkgs`, guarded
|
||||||
|
against duplicate PRs. ADR-0056 **Amendments 2–4** carry the full design.
|
||||||
|
|
||||||
|
## §3. The Homebrew 403 saga + Caddy fix (don't lose this)
|
||||||
|
|
||||||
|
Homebrew `brew install` 403'd while every other tool worked. Root cause,
|
||||||
|
reproduced: Gitea (≥1.25; here 1.26.2) **303-redirects release downloads to a
|
||||||
|
method-bound AWS-SigV4 presigned S3 URL** (OVH), signed for the *incoming*
|
||||||
|
request's HTTP verb. Homebrew **resolves with a HEAD, captures the returned
|
||||||
|
HEAD-signed URL, then runs the download GET against it** → GET-on-a-HEAD-signed
|
||||||
|
URL → 403. (`GET on HEAD-resolved = 403`, `HEAD on HEAD-resolved = 200`,
|
||||||
|
`GET on GET-resolved = 200`.) GET-only tools (install.sh/ps1, binstall, curl)
|
||||||
|
are unaffected. This is a **Homebrew defect** (reusing an ephemeral
|
||||||
|
method-scoped credential as a durable locator); Gitea's per-request signing is
|
||||||
|
correct, and SigV4 *cannot* sign one URL for two verbs. `SERVE_DIRECT=false`
|
||||||
|
would fix it but was **declined** (don't reshape storage for one client).
|
||||||
|
|
||||||
|
**Fix (deployed, "Tier A"):** a Caddy rule answering **HEAD on
|
||||||
|
`…/releases/download/…` directly** (200, no redirect, no body) so brew's
|
||||||
|
resolve records the *original* URL and its download GET redirects fresh →
|
||||||
|
GET-signed → 200. GET untouched; a HEAD carries no payload so nothing can
|
||||||
|
break (a HEAD-probing download manager at most loses a progress-bar size).
|
||||||
|
Reference Caddyfile is in **ADR-0056 Amendment 3**.
|
||||||
|
|
||||||
|
## §4. Immediate next steps
|
||||||
|
|
||||||
|
1. **winget PR #391335:** watch validation — the one likely speed bump is an
|
||||||
|
**AV/SmartScreen manual-review label** (unsigned binary); usually clears.
|
||||||
|
Once a moderator merges, winget is live.
|
||||||
|
2. **Post-merge check (Windows):** `winget install LazyEvaluation.RdbmsPlayground`,
|
||||||
|
confirm the command is **`rdbms-playground`** (it is — a direct single-exe
|
||||||
|
portable takes its PATH alias from `Commands[0]`, which komac set; see §5).
|
||||||
|
3. After merge, future releases are hands-off: the CI `winget` job's
|
||||||
|
`komac update` carries each version (alias inherited from the merged
|
||||||
|
manifest). The release ritual is unchanged from ADR-0054, with the
|
||||||
|
`publish` dispatch now also doing Scoop/Homebrew/winget.
|
||||||
|
|
||||||
|
## §5. Gotchas learned (don't relearn the hard way)
|
||||||
|
|
||||||
|
- **The Caddy HEAD rule is server-side, not in this repo.** Homebrew (and any
|
||||||
|
HEAD-then-GET client) depends on it. Record/back it up.
|
||||||
|
- **GitHub tokens:** komac needs a **classic `public_repo`** PAT — **fine-grained
|
||||||
|
tokens can't open the cross-fork PR** (komac #310: the PR is created on the
|
||||||
|
*target* repo you don't administer, which the fine-grained model can't
|
||||||
|
express). A classic token can't be repo-scoped, so it lives on a **dedicated
|
||||||
|
bot** (`lazyeval-ci`) to bound the blast radius.
|
||||||
|
- **komac fork must pre-exist:** `komac new` auto-fork *races* on winget-pkgs
|
||||||
|
(huge repo) → *"Could not resolve to a Repository 'lazyeval-ci/winget-pkgs'"*.
|
||||||
|
Fork manually first (`gh repo fork microsoft/winget-pkgs --clone=false`),
|
||||||
|
wait, then re-run. Pre-fill `komac new` flags to skip the long interactive
|
||||||
|
prompt parade.
|
||||||
|
- **Direct portable alias = `Commands[0]`, NOT `PortableCommandAlias`.** The
|
||||||
|
latter is **archive/nested-portable-only**; adding it to a bare-exe portable
|
||||||
|
is wrong (komac correctly omits it). The "Commands" prompt → `rdbms-playground`
|
||||||
|
is the on-PATH command. Verified vs winget-cli logic + the 1.6.0 schema.
|
||||||
|
- **install.ps1 / Windows PowerShell 5.1** (the in-box shell — PS7 is opt-in):
|
||||||
|
arch via `PROCESSOR_ARCHITECTURE` env (not `RuntimeInformation::OSArchitecture`,
|
||||||
|
which is absent under 5.1's .NET-Framework facade + StrictMode); force TLS 1.2;
|
||||||
|
`-UseBasicParsing`. Also update `$env:Path` in-session (the persisted User PATH
|
||||||
|
only reaches *new* processes; "restart your shell" was wrong — sign-out/in or
|
||||||
|
the in-session update).
|
||||||
|
- **Gitea release downloads go through OVH S3 presigned URLs** — method-bound,
|
||||||
|
300 s expiry. Never assume HEAD-resolve-then-GET works against them.
|
||||||
|
|
||||||
|
## §6. Parked / deferred (user decisions)
|
||||||
|
|
||||||
|
- **macOS Developer-ID signing + notarization** — pending the Apple account →
|
||||||
|
Organization conversion. Ad-hoc signing covers all package-manager paths
|
||||||
|
(brew-installed binary *runs* on Apple Silicon); Developer-ID only matters for
|
||||||
|
browser-download Gatekeeper trust.
|
||||||
|
- **Windows code signing (Trusted Signing)** — not required to *ship* winget
|
||||||
|
(portable; only MSIX needs signing). Unsigned can earn an AV/SmartScreen
|
||||||
|
manual-review label + a user-run warning. **Lazy Evaluation Ltd (since 2012)
|
||||||
|
clears Trusted Signing's 3-year-org bar** when the user wants to remove the
|
||||||
|
warning (individual onboarding is currently paused; org path is open).
|
||||||
|
- **Release notes / CHANGELOG** — raised this session, not done. If wanted:
|
||||||
|
a `CHANGELOG.md` and/or populated Gitea release bodies, then the CI `winget`
|
||||||
|
job can pass komac `--release-notes-url …/releases/tag/$TAG`.
|
||||||
|
|
||||||
|
## §7. How to take over
|
||||||
|
|
||||||
|
1. Read handoffs 73 → 74 → 75, `CLAUDE.md`, `docs/requirements.md` (D1/D3),
|
||||||
|
and **ADR-0056 (esp. Amendments 1–4)** + the GA plan
|
||||||
|
`docs/plans/20260616-public-availability.md`.
|
||||||
|
2. Workflow unchanged: phased, test-first, `/runda` + DA before commits, ADR
|
||||||
|
amendment + README index-upkeep for decided-area changes, confirm commit
|
||||||
|
messages, never push.
|
||||||
|
3. If `cargo test` is needed, the baseline is **2509 / 1 ignored** (handoff-74).
|
||||||
|
4. Consider a `cargo sweep` at this milestone (`target/` grows).
|
||||||
+17
-9
@@ -86,15 +86,23 @@ since ADR-0027.)
|
|||||||
- [ ] **D3** Released via prebuilt binaries plus Homebrew, Scoop,
|
- [ ] **D3** Released via prebuilt binaries plus Homebrew, Scoop,
|
||||||
`winget`, and `cargo binstall`.
|
`winget`, and `cargo binstall`.
|
||||||
*(Prebuilt binaries + checksums on Gitea releases (D1); **`cargo
|
*(Prebuilt binaries + checksums on Gitea releases (D1); **`cargo
|
||||||
binstall` + crates.io live** (ADR-0056); **Scoop + Homebrew wired**
|
binstall` + crates.io live** (ADR-0056); **Scoop + Homebrew wired and
|
||||||
(ADR-0056 Amendment 2) — `publish.yaml` `scoop-bucket` /
|
validated end-to-end** on real Windows + macOS (ADR-0056 Amendments
|
||||||
`homebrew-tap` jobs render dependency-free manifests from the release
|
2 & 3) — `publish.yaml` `scoop-bucket` / `homebrew-tap` jobs render
|
||||||
`.sha256` sidecars and push them, via the scoped `lazyeval-ci` bot
|
dependency-free manifests from the release `.sha256` sidecars and push
|
||||||
token, to `lazyeval/scoop-bucket` and `lazyeval/homebrew-tap`;
|
them, via the scoped `lazyeval-ci` bot token, to
|
||||||
rendering covered by `scripts/test-package-renders.sh`, end-to-end
|
`lazyeval/scoop-bucket` and `lazyeval/homebrew-tap`; rendering covered
|
||||||
install still to be user-verified. **Remaining: winget** (komac on
|
by `scripts/test-package-renders.sh`. NB: the Homebrew path depends on
|
||||||
Linux CI, or a manual PR). Asset naming
|
a **server-side Caddy rule** answering HEAD on release-download paths
|
||||||
`rdbms-playground-<tag>-<target>` is binstall-friendly.)*
|
directly (Gitea's presigned-S3 redirect is method-bound and brew
|
||||||
|
reuses a HEAD-signed URL for its GET) — see ADR-0056 Amendment 3;
|
||||||
|
that rule lives in the Gitea edge config, not this repo. **winget
|
||||||
|
wired** (ADR-0056 Amendment 4) — a `publish.yaml` `winget` job submits
|
||||||
|
a PR to `microsoft/winget-pkgs` via komac (`LazyEvaluation.RdbmsPlayground`,
|
||||||
|
portable, x64+arm64), guarded against duplicate PRs; pending the
|
||||||
|
**one-time manual `komac new` bootstrap** + Microsoft review before
|
||||||
|
it goes live. Asset naming `rdbms-playground-<tag>-<target>` is
|
||||||
|
binstall-friendly.)*
|
||||||
|
|
||||||
## TUI shell
|
## TUI shell
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user