From 03f3795b7db374656c5df373744122dc2ea3fa31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=E2=88=86I=20Platform?= Date: Sat, 30 May 2026 00:46:50 +0200 Subject: [PATCH] feat: seed Scoop manifest + auto-update workflow Mirror of installer/scoop/fai.json in fai/platform. Source of truth is the platform repo; this is a passive distribution mirror. Auto-update workflow at .forgejo/workflows/update.yml runs every 4 hours, diffs the latest platform release against fai.json, and rewrites version + url + hash when a new version ships. Manual trigger via workflow_dispatch. Users install with: scoop bucket add fai \ https://git.flemming.ai/fai/scoop-bucket scoop install fai End-state matches Phase 1 of docs/releases/go-live-checklist.md. --- .forgejo/workflows/update.yml | 111 ++++++++++++++++++++++++++++++++++ README.md | 25 ++++++++ fai.json | 45 ++++++++++++++ 3 files changed, 181 insertions(+) create mode 100644 .forgejo/workflows/update.yml create mode 100644 README.md create mode 100644 fai.json diff --git a/.forgejo/workflows/update.yml b/.forgejo/workflows/update.yml new file mode 100644 index 0000000..6181714 --- /dev/null +++ b/.forgejo/workflows/update.yml @@ -0,0 +1,111 @@ +# Auto-update workflow for the fai/scoop-bucket repo. +# +# Lives here as the canonical source of truth. The bootstrap +# script (scripts/bootstrap-distribution-repos.sh in +# fai/platform) seeds this file into the bucket repo at +# .forgejo/workflows/update.yml. Edit it here, run the +# bootstrap script, the bucket picks up the new version. +# +# What it does: +# * Every 4 hours, fetches the latest release manifest for +# fai/platform. +# * If the version differs from the one currently in +# fai.json, rewrites version + architecture.64bit.url + +# architecture.64bit.hash and commits. +# * Workflow_dispatch trigger lets you force an update from +# the Forgejo UI. +# +# Linux runner, no Scoop dependency — we replicate scoop's +# checkver+autoupdate logic with curl + jq because installing +# scoop itself needs a Windows runner. + +name: Update Scoop manifest +on: + schedule: + - cron: '0 */4 * * *' + workflow_dispatch: {} + +jobs: + update: + name: Sync fai.json to latest platform release + runs-on: ubuntu-latest + steps: + - name: Checkout via external URL + run: | + set -eu + mkdir -p "$GITHUB_WORKSPACE" + cd "$GITHUB_WORKSPACE" + git init -q + git remote add origin \ + "https://x-access-token:${GITHUB_TOKEN}@git.flemming.ai/${GITHUB_REPOSITORY}.git" + git fetch --depth=1 origin "$GITHUB_REF_NAME" + git checkout -q FETCH_HEAD + + - name: Install jq + curl + sponge + run: | + apt-get update -qq + apt-get install -y --no-install-recommends \ + jq curl moreutils ca-certificates + + - name: Fetch latest manifest + id: manifest + run: | + set -eu + REL=$(curl -fsSL \ + "https://git.flemming.ai/api/v1/repos/fai/platform/releases?limit=1" \ + | jq -r '.[0]') + TAG=$(echo "$REL" | jq -r '.tag_name') + VERSION="${TAG#v}" + # The .exe sha256 comes from the binary sidecar, NOT + # the release manifest — keeps this workflow honest + # against the bytes Scoop users will actually + # download. Same logic as scoop's autoupdate hash + # selector. + SHA=$(curl -fsSL \ + "https://git.flemming.ai/fai/platform/releases/download/${TAG}/fai-windows-x86_64.exe.sha256" \ + | awk '{print $1}') + if [ -z "$SHA" ] || [ "${#SHA}" -ne 64 ]; then + echo "fai-windows-x86_64.exe.sha256 missing or malformed for $TAG" + echo "skip=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + echo "version=$VERSION" >> "$GITHUB_OUTPUT" + echo "sha=$SHA" >> "$GITHUB_OUTPUT" + + - name: Detect manifest version + id: current + if: steps.manifest.outputs.skip != 'true' + run: | + CUR=$(jq -r '.version' fai.json) + echo "version=$CUR" >> "$GITHUB_OUTPUT" + + - name: Rewrite fai.json + id: rewrite + if: | + steps.manifest.outputs.skip != 'true' + && steps.manifest.outputs.version != steps.current.outputs.version + env: + NEW_VERSION: ${{ steps.manifest.outputs.version }} + NEW_SHA: ${{ steps.manifest.outputs.sha }} + run: | + set -eu + jq --arg v "$NEW_VERSION" --arg sha "sha256:$NEW_SHA" \ + '.version = $v + | .architecture."64bit".url = + ("https://git.flemming.ai/fai/platform/releases/download/v" + + $v + "/fai-windows-x86_64.exe#/fai.exe") + | .architecture."64bit".hash = $sha' \ + fai.json | sponge fai.json + echo "rewritten=true" >> "$GITHUB_OUTPUT" + + - name: Commit + push + if: steps.rewrite.outputs.rewritten == 'true' + env: + NEW_VERSION: ${{ steps.manifest.outputs.version }} + run: | + set -eu + git config user.email "platform@flemming.ai" + git config user.name "fai-scoop-bot" + git add fai.json + git commit -s -m "chore: scoop manifest -> v${NEW_VERSION}" + git push origin "HEAD:${GITHUB_REF_NAME}" diff --git a/README.md b/README.md new file mode 100644 index 0000000..52fd8a6 --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# scoop-bucket + +Distribution mirror for the [F∆I Platform](https://git.flemming.ai/fai/platform). + +This repo holds one file — `fai.json` — which is a copy of +[`installer/scoop/fai.json`](https://git.flemming.ai/fai/platform/src/branch/main/installer/scoop/fai.json) +in the platform repo. The platform repo is the source of +truth; this repo exists as a separate target so end users can +add it as a tap / bucket / channel without subscribing to +the whole platform tree. + +Updates land here automatically via +`.forgejo/workflows/update.yml` — a 4-hourly cron that +diffs the latest platform release against this repo's +manifest and rewrites it when a new version ships. To force +an immediate update, trigger the **Workflow_dispatch** action +in the Forgejo UI. + +When the workflow itself or the underlying manifest format +changes, re-seed from the platform repo by running +`scripts/bootstrap-distribution-repos.sh`. + +Issues, PRs, and ad-hoc questions belong at +`https://git.flemming.ai/fai/platform` — this repo is intentionally +quiet. diff --git a/fai.json b/fai.json new file mode 100644 index 0000000..ea9494f --- /dev/null +++ b/fai.json @@ -0,0 +1,45 @@ +{ + "$schema": "https://raw.githubusercontent.com/ScoopInstaller/Scoop/master/schema.json", + "version": "0.12.1", + "description": "Deterministic workflow engine for AI-assisted data processing in regulated environments.", + "homepage": "https://flemming.ai/", + "license": "Apache-2.0", + "architecture": { + "64bit": { + "url": "https://git.flemming.ai/fai/platform/releases/download/v0.12.1/fai-windows-x86_64.exe#/fai.exe", + "hash": "sha256:0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "bin": "fai.exe", + "post_install": [ + "Write-Host ''", + "Write-Host 'F∆I installed. Bootstrap the per-user layout with:'", + "Write-Host ' fai bootstrap'", + "Write-Host 'then'", + "Write-Host ' fai daemon start'", + "Write-Host ''" + ], + "checkver": { + "url": "https://git.flemming.ai/fai/platform/releases.atom", + "regex": "v([\\d.]+)" + }, + "autoupdate": { + "architecture": { + "64bit": { + "url": "https://git.flemming.ai/fai/platform/releases/download/v$version/fai-windows-x86_64.exe#/fai.exe", + "hash": { + "url": "$url.sha256", + "regex": "^([a-fA-F0-9]{64})" + } + } + } + }, + "notes": [ + "F∆I includes a sandboxed WASM runtime. First launch may", + "trigger SmartScreen because the binary is not yet", + "Authenticode-signed; this is tracked as the remaining", + "Windows half of system-gap S-16. Verify the binary", + "manually against its ECDSA signature sidecar:", + " fai admin verify --self" + ] +}