-
Notifications
You must be signed in to change notification settings - Fork 0
246 lines (229 loc) · 10.9 KB
/
Copy pathsourcebuild-proof.yml
File metadata and controls
246 lines (229 loc) · 10.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# AgentBridge FROM SOURCE — experimental proof build (NOT the release pipeline).
#
# Validates the Flathub build model end-to-end on OUR CI: the engine is compiled from
# the AgentBridge source tag inside a flatpak sandbox, NuGet is restored OFFLINE from a
# local feed, and the bundle is produced with the same web client + branding as the
# release bundle. Run manually:
#
# gh workflow run sourcebuild-proof.yml -f version=v1.26.09.08 # or "latest"
#
# Build commands have NO network in flatpak-builder (1.2 on Debian) — everything the
# engine needs is staged as module sources before the build:
# - .NET SDK tarball (module source)
# - nuget-sources.json (one source per nupkg, staged into ./nuget-sources by the
# flatpak-dotnet-generator, run inside org.freedesktop.Sdk//24.08 + dotnet10 ext)
# - kokoro.onnx + Tools/ + .playwright extracted from the release archive
# (packaging/.proof-staging, gitignored)
# - GiraffeAI web client zip + branding
name: Source-Build Proof (experimental)
on:
workflow_dispatch:
inputs:
version:
description: "AgentBridge tag to build from source (default: latest)"
required: false
default: latest
concurrency:
group: sourcebuild-proof
cancel-in-progress: false
env:
GH_TOKEN: ${{ github.token }}
APPID: io.github.graphene_lab.agentbridge
UPSTREAM: Graphene-Lab/AgentBridge
CLIENT_REPO: Graphene-Lab/GiraffeAI
STAGING: packaging/.proof-staging
jobs:
proof:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install flatpak toolchain
shell: bash
run: |
sudo apt-get update -qq
sudo apt-get install -y -qq flatpak flatpak-builder librsvg2-bin xvfb
# Everything flatpak needs in this job, installed once up-front:
# org.gnome.*48 → the app runtime/SDK (builder).
- name: Add Flathub remote + install GNOME runtime/SDK (x86_64)
shell: bash
run: |
sudo flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
sudo flatpak install --system -y --noninteractive flathub \
org.gnome.Platform//48 org.gnome.Sdk//48
# Host .NET: used ONLY to restore the project into a flat packages dir whose
# *.nupkg.sha512 files become the offline feed. Using the same SDK version as the
# build module (10.0.400) keeps every package (runtime packs included) consistent.
- name: Setup .NET (host, for the offline feed)
uses: actions/setup-dotnet@v4
with:
dotnet-version: '10.0.400'
- name: Resolve upstream tag + commit
shell: bash
run: |
latest_tag() {
curl -fsSL "https://api.github.com/repos/$1/releases/latest" 2>/dev/null \
| python3 -c 'import sys,json; print(json.load(sys.stdin).get("tag_name") or "")' 2>/dev/null \
|| true
}
TAG="${{ inputs.version }}"
if [ -z "$TAG" ] || [ "$TAG" = "latest" ]; then
TAG="$(latest_tag "${{ env.UPSTREAM }}")"
fi
[ -n "$TAG" ] || { echo "::error::cannot resolve upstream release"; exit 1; }
VER="${TAG#v}"
COMMIT="$(git ls-remote "https://github.com/${{ env.UPSTREAM }}" "refs/tags/${TAG}" | cut -f1)"
[ -n "$COMMIT" ] || { echo "::error::cannot resolve commit of tag ${TAG}"; exit 1; }
CTAG="$(latest_tag "${{ env.CLIENT_REPO }}")"
echo "tag=$TAG version=$VER commit=$COMMIT"
echo "VER=$VER" >> "$GITHUB_ENV"
echo "COMMIT=$COMMIT" >> "$GITHUB_ENV"
echo "CVER=${CTAG#v}" >> "$GITHUB_ENV"
- name: Download Giraffe AI web client + compute checksum
shell: bash
run: |
URL="https://github.com/${{ env.CLIENT_REPO }}/releases/download/v${CVER}/giraffeai-${CVER}.zip"
curl -fsSL -o giraffeai.zip "$URL"
echo "CLIENT_SHA256=$(sha256sum giraffeai.zip | cut -d' ' -f1)" >> "$GITHUB_ENV"
- name: Download .NET SDK + compute checksum
shell: bash
run: |
URL="https://builds.dotnet.microsoft.com/dotnet/Sdk/10.0.400/dotnet-sdk-10.0.400-linux-x64.tar.gz"
curl -fsSL -o dotnet-sdk.tar.gz "$URL"
echo "SDK_SHA256=$(sha256sum dotnet-sdk.tar.gz | cut -d' ' -f1)" >> "$GITHUB_ENV"
ls -lh dotnet-sdk.tar.gz
rm -f dotnet-sdk.tar.gz
- name: Clone AgentBridge source at the release commit
shell: bash
run: |
mkdir -p "${{ env.STAGING }}"
git clone --filter=blob:none --no-checkout \
"https://github.com/${{ env.UPSTREAM }}" "${{ env.STAGING }}/src"
git -C "${{ env.STAGING }}/src" checkout "${{ env.COMMIT }}"
- name: Generate nuget-sources.json (offline feed descriptor)
shell: bash
run: |
TMP="${{ env.STAGING }}/nugettmp"
# Same publish properties as the build module, restore only: guarantees the
# feed contains every package the module publish will resolve offline
# (self-contained runtime packs + ILLink included).
dotnet restore "${{ env.STAGING }}/src/AgentBridge.csproj" \
-r linux-x64 --packages "$TMP" \
-p:SelfContained=true \
-p:PublishSingleFile=true \
-p:IncludeNativeLibrariesForSelfExtract=true \
-p:NuGetAudit=false
python3 - "$TMP" <<'PY'
import base64, binascii, json, pathlib, sys
root = pathlib.Path(sys.argv[1])
entries = []
for sha_file in sorted(root.rglob("*.nupkg.sha512")):
pkg_id = sha_file.parent.parent.name
version = sha_file.parent.name
filename = f"{pkg_id}.{version}.nupkg"
url = f"https://api.nuget.org/v3-flatcontainer/{pkg_id.lower()}/{version}/{filename}"
# The .nupkg.sha512 files NuGet writes are base64; flatpak-builder wants hex.
sha512 = binascii.hexlify(base64.b64decode(sha_file.read_text().strip())).decode()
entries.append({
"type": "file",
"url": url,
"sha512": sha512,
"dest": "nuget-sources",
"dest-filename": filename,
})
pathlib.Path("packaging/source/nuget-sources.json").write_text(
json.dumps(sorted(entries, key=lambda e: e["dest-filename"]), indent=2)
)
print("packages:", len(entries))
PY
python3 -c "import json;print(json.dumps(json.load(open('packaging/source/nuget-sources.json'))[0],indent=1)[:400])"
- name: Stage payload (kokoro.onnx, Tools/, .playwright) from the release archive
shell: bash
run: |
mkdir -p "${{ env.STAGING }}/payload"
curl -fsSL -o release.tar.gz \
"https://github.com/${{ env.UPSTREAM }}/releases/download/v${VER}/agentbridge-linux-x64.tar.gz"
tar -xzf release.tar.gz -C "${{ env.STAGING }}/payload" \
./Tools ./.playwright ./kokoro.onnx
rm -f release.tar.gz
ls -ld "${{ env.STAGING }}/payload"/.playwright "${{ env.STAGING }}/payload"/Tools \
|| { echo "::error::payload staging incomplete"; exit 1; }
ls -lh "${{ env.STAGING }}/payload"/kokoro.onnx
- name: Generate launcher icons (giraffe on brand gradient)
shell: bash
run: |
APPID="${{ env.APPID }}"
python3 - <<'PY'
import pathlib, re
src = pathlib.Path("packaging/branding/giraffe.svg").read_text()
m = re.search(r'<g[^>]*>.*?</g>', src, re.S)
if not m:
raise SystemExit("cannot find the giraffe group in giraffe.svg")
body = m.group(0)
svg = f'''<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512">
<defs><linearGradient id="bg" x1="0" y1="0" x2="0" y2="1">
<stop offset="0" stop-color="#6c5ce7"/><stop offset="1" stop-color="#3b2f9e"/>
</linearGradient></defs>
<rect width="512" height="512" rx="112" fill="url(#bg)"/>
<g fill="#ffffff"><g transform="translate(60 96) scale(0.98 0.98)">{body}</g></g>
</svg>'''
pathlib.Path("build-icon.svg").write_text(svg)
PY
for s in 64 128 256 512; do
mkdir -p "build-icons/icons/hicolor/${s}x${s}/apps"
rsvg-convert -w "$s" -h "$s" build-icon.svg \
-o "build-icons/icons/hicolor/${s}x${s}/apps/${APPID}.png"
done
- name: Render the source-build manifest
shell: bash
run: |
python3 - <<'PY'
import json, pathlib, os, yaml
root = pathlib.Path(".").resolve()
raw = (root / "packaging" / "source" / "agentbridge-source.yml.tmpl").read_text()
for key, value in {
"@@VERSION@@": os.environ["VER"],
"@@COMMIT@@": os.environ["COMMIT"],
"@@SDK_SHA256@@": os.environ["SDK_SHA256"],
"@@CLIENT_VERSION@@": os.environ["CVER"],
"@@CLIENT_SHA256@@": os.environ["CLIENT_SHA256"],
}.items():
raw = raw.replace(key, value)
doc = yaml.safe_load(raw)
# flatpak-builder 1.2 cannot expand a nested sources .json: merge the
# generator output (one "file" source per nupkg) directly into the module.
nuget = json.loads((root / "packaging" / "source" / "nuget-sources.json").read_text())
engine = next(m for m in doc["modules"] if m["name"] == "agentbridge-source")
engine["sources"].extend(nuget)
(root / "packaging" / "source" / "agentbridge.yml").write_text(
yaml.safe_dump(doc, sort_keys=False, default_flow_style=False, width=1000000)
)
print("rendered packaging/source/agentbridge.yml with",
len(nuget), "nuget sources merged")
PY
- name: Build engine from source (offline restore)
shell: bash
run: |
sudo flatpak-builder \
--force-clean \
--disable-rofiles-fuse \
--repo=repo-proof \
.build-proof \
packaging/source/agentbridge.yml
sudo flatpak build-bundle \
--runtime-repo=https://flathub.org/repo/flathub.flatpakrepo \
repo-proof \
agentbridge-source-proof.flatpak \
${{ env.APPID }} \
master
ls -lh agentbridge-source-proof.flatpak
sha256sum agentbridge-source-proof.flatpak
- name: Smoke check (install + doctor)
shell: bash
continue-on-error: true
run: |
# Host runners have no XDG_RUNTIME_DIR for the ubuntu user — flatpak needs one.
export XDG_RUNTIME_DIR="$(mktemp -d)"
chmod 700 "$XDG_RUNTIME_DIR"
flatpak install --user -y --noninteractive ./agentbridge-source-proof.flatpak
flatpak run --user --command=agent-desktop ${{ env.APPID }} --doctor