ci(publish): wire winget job via komac (D3 §3d)
Add the 4th publish.yaml sibling job: opens a PR to microsoft/winget-pkgs with komac (pinned 2.16.0 prebuilt) for LazyEvaluation.RdbmsPlayground (portable, x64 + arm64). Unlike scoop/homebrew it's a PR into Microsoft's central, human-gated catalog - async and validated on their side. - Auth: a classic public_repo GitHub PAT on a dedicated bot account (lazyeval-ci; fine-grained tokens can't open the cross-fork PR - komac #310), as the WINGET_GITHUB_TOKEN secret, job-scoped and passed to the API guards via a 0600 curl config file (never argv). - Idempotent via two guards before submitting (already-merged version + already-open PR) so a repeated publish dispatch can't open a duplicate. - No actions/checkout (komac works off URLs + the GitHub API). Docs: ADR-0056 Amendment 4 - the model, the one-time manual `komac new` bootstrap recipe (flags verified vs komac 2.16.0), and first-run learnings: the fork must pre-exist, and a direct single-exe portable takes its PATH alias from Commands[0] (not PortableCommandAlias, which is nested-only). Plus README index + requirements D3. Wiring only; going live needs the bootstrap PR (#391335, submitted) to merge.
This commit is contained in:
@@ -198,6 +198,87 @@ jobs:
|
||||
git push origin HEAD:main
|
||||
echo "homebrew: tap updated to rdbms-playground $VER."
|
||||
|
||||
# winget remains a future sibling job here (komac on Linux CI, or a manual PR
|
||||
# to microsoft/winget-pkgs). No `needs:` between jobs — each is independent and
|
||||
# idempotent, so one failing or being added never breaks another.
|
||||
# Update the winget package (Windows) by opening a PR to microsoft/winget-pkgs
|
||||
# with komac. Unlike scoop-bucket/homebrew-tap (which push to OUR repos and are
|
||||
# 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.
|
||||
|
||||
Reference in New Issue
Block a user