<# .SYNOPSIS One-line web launcher for a ShopDB dev workstation. .DESCRIPTION The piece that makes `iex (irm .../get.ps1)` work. dev-bootstrap.ps1 operates on a local clone, so it cannot be run straight from the web. This launcher fills that gap: it clones (or updates) the repo at the channel branch into a stable local path, then hands off to scripts/dev-bootstrap.ps1 for the real dependency-check / build / up work. Channel is chosen by an environment variable so a pure `iex` pipe (which cannot pass parameters) still selects stable vs edge: # Bleeding edge (dev-be): $env:SHOPDB_CHANNEL='edge' $env:SHOPDB_TOKEN='ghp_yourtoken' $h=@{ Authorization="token $env:SHOPDB_TOKEN" } iex (irm -Headers $h https://raw.githubusercontent.com/ge-aero/shopdb-flask/wilm/scripts/get.ps1) ge-aero/shopdb-flask is a PRIVATE repo, so both the raw fetch of this launcher AND the git clone it performs need a GitHub token. The raw fetch is authenticated by the -Headers on irm above; the clone is authenticated here by reading the same token from the environment (SHOPDB_TOKEN, or GITHUB_TOKEN as a fallback) and using it in the clone URL. Anonymous access returns 404. SHOPDB_DIR overrides the clone location (default %USERPROFILE%\shopdb-dev). .NOTES ASCII only, no emoji or smart punctuation, per repo style. PowerShell 5.1+. Runs git-checkout of the channel branch, so it needs Git; dev-bootstrap.ps1 offers to winget-install anything else that is missing. #> $ErrorActionPreference = 'Stop' # Private-repo access token, used for the git clone/fetch below. The same token # authenticated the raw fetch of this script (via irm -Headers). Prefer the # ShopDB-specific var so a pilot can keep an unrelated GITHUB_TOKEN in place. $token = if ($env:SHOPDB_TOKEN) { $env:SHOPDB_TOKEN } elseif ($env:GITHUB_TOKEN) { $env:GITHUB_TOKEN } else { '' } if (-not $token) { throw 'No token found. Set $env:SHOPDB_TOKEN (a GitHub PAT with repo read) before running; the repo is private.' } # x-access-token is GitHub's documented username for token-in-URL auth; it works # for classic PATs and fine-grained tokens alike. Kept out of any Write-Host so # the secret never lands in the transcript. $repoUrl = "https://x-access-token:$token@github.com/ge-aero/shopdb-flask.git" $channel = if ($env:SHOPDB_CHANNEL) { $env:SHOPDB_CHANNEL } else { 'stable' } if ($channel -notin @('stable', 'edge')) { throw "SHOPDB_CHANNEL must be 'stable' or 'edge' (got '$channel')." } $branch = if ($channel -eq 'edge') { 'dev-be' } else { 'main' } $target = if ($env:SHOPDB_DIR) { $env:SHOPDB_DIR } else { Join-Path $env:USERPROFILE 'shopdb-dev' } Write-Host "ShopDB web launcher" -ForegroundColor White Write-Host " Channel : $channel ($branch)" -ForegroundColor White Write-Host " Target : $target" -ForegroundColor White if (-not (Get-Command git -ErrorAction SilentlyContinue)) { throw 'git is required to clone the repo. Install Git (winget install Git.Git) and re-run.' } if (Test-Path (Join-Path $target '.git')) { Write-Host "==> Updating existing clone" -ForegroundColor Cyan # Fetch by explicit tokenized URL, not `origin`: origin is deliberately the # clean tokenless URL (see the clone path below), so a bare `fetch origin` # would 404 against the private repo. Passing the URL keeps the token off # disk while still authenticating this pull. git -C $target fetch $repoUrl $branch if ($LASTEXITCODE -ne 0) { throw "git fetch failed ($LASTEXITCODE)." } git -C $target checkout $branch if ($LASTEXITCODE -ne 0) { throw "git checkout failed ($LASTEXITCODE)." } git -C $target merge --ff-only FETCH_HEAD if ($LASTEXITCODE -ne 0) { throw "git merge --ff-only failed ($LASTEXITCODE)." } } else { Write-Host "==> Cloning $branch" -ForegroundColor Cyan git clone --branch $branch $repoUrl $target if ($LASTEXITCODE -ne 0) { throw "git clone failed ($LASTEXITCODE)." } # Scrub the token out of the persisted remote: `git clone` writes the full # URL (token included) into .git/config. Reset origin to the clean URL so the # secret does not sit on disk. Fetch/pull above still work because this only # runs on the fresh-clone path; a returning pilot re-fetches with a clean # origin and their own credential helper / token as usual. git -C $target remote set-url origin 'https://github.com/ge-aero/shopdb-flask.git' if ($LASTEXITCODE -ne 0) { throw "git remote set-url failed ($LASTEXITCODE)." } } $bootstrap = Join-Path $target 'scripts\dev-bootstrap.ps1' if (-not (Test-Path $bootstrap)) { throw "dev-bootstrap.ps1 not found at $bootstrap. Is the branch correct?" } Write-Host "==> Handing off to dev-bootstrap.ps1" -ForegroundColor Cyan & $bootstrap -Channel $channel