Skip to content

bootstrap v2026.09.28-2

Choose a tag to compare

@github-actions github-actions released this 28 Sep 07:17
· 2 commits to main since this release

Windows 1.47.0

Added

  • A release archive is a whole install now. It used to hold the platform
    directory alone, without the configs the script deploys from the repo root -
    starship.toml, the tool themes, mise/, tools/cli-parity.conf - so an install
    from it could not finish its shell and theme phases. Each archive now
    unpacks to one bootstrap/ directory laid out as the repo: the platform's own
    directory and every top-level entry but the other two platforms. It also
    carries a RELEASE file naming the tag and the repo.
  • An archive install updates itself like a checkout: when a newer release
    is out, a run you are sitting at offers it, downloads that release's zip,
    checks it against the published .sha256, unpacks it into a temp directory
    and copies it over the install - the same directory, so the daily task still
    finds the script. A download that fails or does not match leaves the install
    as it was. An archive from before this release has no RELEASE file; unpack
    this one once by hand and it updates from then on.
  • Update from a run: when preflight finds a newer release, a run you are
    sitting at asks Update to vX and rerun? [y/N]. Yes fetches, moves the
    checkout to the tag - a branch fast-forwards, a detached checkout of a tag
    moves to the new one - and reruns the new script with the same arguments and
    -SkipUpdateCheck. Local changes, or a branch with commits the release
    lacks, and it refuses and says why rather than guessing. The daily task,
    -WhatIf and -Doctor only print the line, as before.
  • -Select: choose which packages this machine has. A menu of every
    winget package and uv tool in the manifest, drawn by the script itself: a
    section per group with its packages beneath, each with a [x] or [ ] box,
    the installed version and the current pick pre-ticked. Space on a package
    ticks it; on a section it ticks all of it - or clears it, when all of it was
    ticked - and the section shows [x], [-] or [ ] for all, some or none.
    Not fzf: fzf marks only ticked lines, with no empty box for the rest, and a
    whole-section toggle from inside it takes a shell command per keypress. It
    needs no fzf, so it works on a first run too. Ticked is installed; unticked
    and installed is uninstalled, after one confirmation listing all of it.
    Declining abandons the whole pick rather than saving it without the
    removals, which would leave those packages installed but unwanted, and
    never offered for removal again.
  • The pick is saved to %LOCALAPPDATA%\windows-bootstrap\selection.json,
    beside last-run, and every later run follows it, the daily task included.
    It keeps two lists: Selected, what was ticked, and Known, everything the
    menu offered - so an unticked package can be told from one the manifest
    gained since. With no file every package is wanted, exactly as before.
  • Required in packages.psd1: ids that are always installed and show
    locked in the menu - pwsh, git, uv and mise, which other phases stand on.
    Optional, so an older manifest still loads; an id no group lists fails the
    run up front.
  • New packages are asked about, not assumed. A manual run asks once per
    package the manifest gained since the last pick and remembers the answer
    either way. An unattended run installs none of them and reports each as
    deselected, so nothing arrives on the machine that nobody chose. A
    section with nothing ticked counts as switched off: its newcomers are left
    out without asking.
  • User-scope packages uninstall from an elevated run. winget refuses
    (0x8A15007D) to remove a package installed per user - most portable CLIs -
    from an administrator process. That one call is rerun un-elevated as the
    same user, through a throwaway scheduled task with RunLevel Limited that is
    removed when it finishes.
  • What the menu offers to remove follows the machine: anything unticked
    and still installed that a menu has offered before. A removal that failed
    is offered again on the next -Select instead of being stranded as
    unticked-but-installed.
  • Result actions removed, would-remove and deselected, and the run
    history now records a removal as -id.

Removed

  • ILSpy, added in 1.46.0: dropped before anyone depended on it. Taking it
    out of the manifest stops installs and upgrades; a copy already installed
    stays until winget uninstall icsharpcode.ILSpy.
  • Sysinternals Suite, added in 1.46.0: winget's manifest pins the hash of
    SysinternalsSuite.zip, which Microsoft replaces in place at the same URL
    without a new version, so the install fails the hash check - and an
    elevated winget rightly refuses to skip it - every time the zip moves until
    the manifest catches up.

Linux 1.40.0

Added

  • A release archive is a whole install now. It used to hold the platform
    directory alone, without the configs the script deploys from the repo root -
    starship.toml, the tool themes, mise/, tools/cli-parity.conf - so an install
    from it could not finish its shell and theme phases. Each archive now
    unpacks to one bootstrap/ directory laid out as the repo: the platform's own
    directory and every top-level entry but the other two platforms. It also
    carries a RELEASE file naming the tag and the repo.
  • An archive install updates itself like a checkout: when a newer release
    is out, a run you are sitting at offers it, downloads that release's
    tarball, checks it against the published .sha256, unpacks it into a temp
    directory and copies it over the install - the same directory, so the
    systemd timer still finds the script. A download that fails or does not
    match leaves the install as it was. An archive from before this release has
    no RELEASE file; unpack this one once by hand and it updates from then on.
  • Update from a run: when preflight finds a newer release, a run you are
    sitting at asks Update to vX and rerun? [y/N]. Yes fetches, moves the
    checkout to the tag - a branch fast-forwards, a detached checkout of a tag
    moves to the new one - and reruns the new script with the same arguments and
    --skip-update-check. Local changes, or a branch with commits the release
    lacks, and it refuses and says why rather than guessing. The systemd timer,
    --dry-run, --doctor and a run as root only print the line: git writing
    into your checkout as root would leave files you could not change. The rerun
    is an exec: bash reads a script as it runs, so the old process must not go
    on over a file that just changed under it.

macOS 1.43.0

Added

  • A release archive is a whole install now. It used to hold the platform
    directory alone, without the configs the script deploys from the repo root -
    starship.toml, the tool themes, mise/, tools/cli-parity.conf - so an install
    from it could not finish its shell and theme phases. Each archive now
    unpacks to one bootstrap/ directory laid out as the repo: the platform's own
    directory and every top-level entry but the other two platforms. It also
    carries a RELEASE file naming the tag and the repo.
  • An archive install updates itself like a checkout: when a newer release
    is out, a run you are sitting at offers it, downloads that release's
    tarball, checks it against the published .sha256, unpacks it into a temp
    directory and copies it over the install - the same directory, so the
    launchd agent still finds the script. A download that fails or does not
    match leaves the install as it was. An archive from before this release has
    no RELEASE file; unpack this one once by hand and it updates from then on.
  • Update from a run: when preflight finds a newer release, a run you are
    sitting at asks Update to vX and rerun? [y/N]. Yes fetches, moves the
    checkout to the tag - a branch fast-forwards, a detached checkout of a tag
    moves to the new one - and reruns the new script with the same arguments and
    --skip-update-check. Local changes, or a branch with commits the release
    lacks, and it refuses and says why rather than guessing. The launchd agent,
    --dry-run and --doctor only print the line. The rerun is an exec: bash
    reads a script as it runs, so the old process must not go on over a file
    that just changed under it.
  • --select: choose which packages this Mac has, the same design as
    Windows 1.47.0. A menu of every formula and cask in the manifest, drawn by
    the script: a section per group with its packages beneath, each with a
    [x] or [ ] box and its installed version, the current pick pre-ticked.
    Space on a section ticks all of it, or clears it when all of it was ticked,
    and the section shows [x], [-] or [ ]. Keys are read from /dev/tty
    a byte at a time; everything else - the rows, a toggle, a frame - is plain
    functions over indexed arrays, since bash 3.2 has no associative ones.
  • Unticked and installed is uninstalled with brew uninstall, after one
    confirmation listing all of it; declining keeps everything and saves
    nothing. What is offered follows the machine - unticked, installed, offered
    before - so a formula brew refused to remove because another depends on it
    is offered again next time.
  • The pick is saved to ~/.local/state/bootstrap-macos/selection as plain
    yes/no lines, and every later run follows it, the launchd agent
    included. A line that is neither makes the file untrusted, and every package
    is wanted - a garbled file never unticks everything. No file, no change.
  • REQUIRED in packages.conf - git, mise and uv - always installed and
    locked in the menu. Optional, so an older manifest still loads; an id no
    group lists fails the run up front.
  • New packages are asked about once on a manual run and the answer kept;
    the agent installs none of them and reports each as deselected. A section
    with nothing ticked counts as switched off, and its newcomers are left out
    without asking.
  • The run history records a removal as -pkg, and the menu restores the
    terminal on Ctrl-C as well as on exit.

Removed

  • ILSpy, added in 1.42.0: dropped before anyone depended on it. Taking it
    out of the manifest stops installs and upgrades; a copy already installed
    stays until brew uninstall --cask ilspy.