Skip to content

Commit 03dad33

Browse files
committed
Merge branch 'main' into posthog-code/grow-103-autoresearch
Resolve conflict in TaskInput.tsx: combine main's file-preview restructure with the autoresearch composer additions. Generated-By: PostHog Code Task-Id: ed0d2aad-b4b6-4595-9677-b7a4f3959183
2 parents 6fefe5d + a88f688 commit 03dad33

310 files changed

Lines changed: 19004 additions & 1888 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/code-release.yml

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,21 @@ jobs:
223223
apps/code/out/*-mac.zip \
224224
apps/code/out/*.blockmap
225225
226+
# Hash the same files uploaded above; finalize-release turns these into
227+
# the download tables in the release notes.
228+
- name: Compute artifact checksums
229+
env:
230+
MATRIX_ARCH: ${{ matrix.arch }}
231+
working-directory: apps/code/out
232+
run: shasum -a 256 *.dmg *-mac.zip *.blockmap > "checksums-macos-$MATRIX_ARCH.txt"
233+
234+
- name: Upload checksums artifact
235+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
236+
with:
237+
name: checksums-macos-${{ matrix.arch }}
238+
path: apps/code/out/checksums-macos-${{ matrix.arch }}.txt
239+
retention-days: 1
240+
226241
- name: Upload mac manifest artifact
227242
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
228243
with:
@@ -332,6 +347,20 @@ jobs:
332347
$files = $items | Select-Object -ExpandProperty FullName
333348
gh release upload "v$env:APP_VERSION" --repo PostHog/code --clobber @files
334349
350+
# Hash the same files uploaded above (minus latest.yml); finalize-release
351+
# turns these into the download tables in the release notes.
352+
- name: Compute artifact checksums
353+
shell: bash
354+
working-directory: apps/code/out
355+
run: sha256sum *.exe *.blockmap > checksums-windows-x64.txt
356+
357+
- name: Upload checksums artifact
358+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
359+
with:
360+
name: checksums-windows-x64
361+
path: apps/code/out/checksums-windows-x64.txt
362+
retention-days: 1
363+
335364
publish-linux:
336365
needs: [prepare-release]
337366
strategy:
@@ -444,6 +473,21 @@ jobs:
444473
apps/code/out/*.deb \
445474
apps/code/out/*.rpm
446475
476+
# Hash the same files uploaded above; finalize-release turns these into
477+
# the download tables in the release notes.
478+
- name: Compute artifact checksums
479+
env:
480+
MATRIX_ARCH: ${{ matrix.arch }}
481+
working-directory: apps/code/out
482+
run: sha256sum *.AppImage *.deb *.rpm > "checksums-linux-$MATRIX_ARCH.txt"
483+
484+
- name: Upload checksums artifact
485+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
486+
with:
487+
name: checksums-linux-${{ matrix.arch }}
488+
path: apps/code/out/checksums-linux-${{ matrix.arch }}.txt
489+
retention-days: 1
490+
447491
finalize-release:
448492
needs: [publish-macos, publish-windows, publish-linux]
449493
# Publish only when every platform built successfully. Without an `if:` override
@@ -471,6 +515,7 @@ jobs:
471515
with:
472516
sparse-checkout: |
473517
apps/code/scripts/merge-mac-manifests.mjs
518+
apps/code/scripts/generate-release-download-tables.mjs
474519
sparse-checkout-cone-mode: false
475520

476521
- name: Setup Node.js
@@ -508,10 +553,19 @@ jobs:
508553
run: |
509554
gh release upload "v$APP_VERSION" --repo PostHog/code --clobber /tmp/latest-mac.yml
510555
556+
- name: Download checksum artifacts
557+
uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
558+
with:
559+
pattern: checksums-*
560+
merge-multiple: true
561+
path: /tmp/checksums
562+
511563
- name: Publish GitHub release
512564
env:
513565
GH_TOKEN: ${{ steps.app-token.outputs.token }}
514566
APP_VERSION: ${{ steps.version.outputs.version }}
515567
run: |
516568
gh api repos/PostHog/code/releases/generate-notes -f tag_name="v$APP_VERSION" --jq '.body' > /tmp/release-notes.md
569+
printf '\n' >> /tmp/release-notes.md
570+
node apps/code/scripts/generate-release-download-tables.mjs "$APP_VERSION" /tmp/checksums >> /tmp/release-notes.md
517571
gh release edit "v$APP_VERSION" --repo PostHog/code --draft=false --notes-file /tmp/release-notes.md

.github/workflows/code-tag.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ jobs:
2626
contains(github.event.pull_request.labels.*.name, 'Create release'))
2727
permissions:
2828
contents: write
29+
actions: write
2930
runs-on: ubuntu-latest
3031
steps:
3132
- name: Get app token
@@ -45,7 +46,7 @@ jobs:
4546
id: quiet
4647
if: github.event_name == 'schedule' || (github.event_name == 'workflow_dispatch' && github.event.inputs.quiet_retries != '0')
4748
env:
48-
GH_TOKEN: ${{ steps.app-token.outputs.token }}
49+
GH_TOKEN: ${{ github.token }}
4950
QUIET_RETRIES: ${{ github.event.inputs.quiet_retries || 0 }}
5051
run: |
5152
RETRIES="${QUIET_RETRIES}"

.github/workflows/test.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,20 @@ jobs:
7171
- name: Run tests
7272
run: pnpm test
7373

74+
- name: Upload test results to Trunk
75+
# Run even when tests fail so flaky/failed results are still reported,
76+
# but never let an upload problem fail the job.
77+
if: ${{ !cancelled() }}
78+
continue-on-error: true
79+
uses: trunk-io/analytics-uploader@385f1ccdf345b4532dc4b6c665dd432b702b8e28 # v2.1.2
80+
with:
81+
# Scope to each package root. A bare **/junit.xml glob descends into
82+
# node_modules, where pnpm symlinks workspace packages, and uploads
83+
# every report many times over.
84+
junit-paths: "apps/*/junit.xml,packages/*/junit.xml"
85+
org-slug: posthog-inc
86+
token: ${{ secrets.TRUNK_API_TOKEN }}
87+
7488
integration-test:
7589
needs: changes
7690
# Fail closed: if change detection itself failed, run instead of skipping.
@@ -140,6 +154,17 @@ jobs:
140154
env:
141155
CI: true
142156

157+
- name: Upload test results to Trunk
158+
# Run even when E2E tests fail so flaky/failed results are still
159+
# reported, but never let an upload problem fail the job.
160+
if: ${{ !cancelled() }}
161+
continue-on-error: true
162+
uses: trunk-io/analytics-uploader@385f1ccdf345b4532dc4b6c665dd432b702b8e28 # v2.1.2
163+
with:
164+
junit-paths: "apps/code/tests/e2e/junit.xml"
165+
org-slug: posthog-inc
166+
token: ${{ secrets.TRUNK_API_TOKEN }}
167+
143168
- name: Upload Playwright report
144169
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
145170
if: failure()

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ test-results/
5757
*storybook.log
5858
.session-store.json
5959
.playwright-mcp
60+
# Trunk Flaky Tests JUnit reports (one per package, uploaded from CI)
61+
junit.xml
6062

6163
# Downloaded binaries
6264
apps/code/resources/codex-acp/

apps/code/electron.vite.config.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { builtinModules, createRequire } from "node:module";
33
import path from "node:path";
44
import { fileURLToPath } from "node:url";
55
import tailwindcss from "@tailwindcss/vite";
6-
import { devtools } from "@tanstack/devtools-vite";
76
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
87
import react from "@vitejs/plugin-react";
98
import { defineConfig } from "electron-vite";
@@ -199,7 +198,6 @@ export default defineConfig(({ mode }) => {
199198
renderer: {
200199
root: __dirname,
201200
plugins: [
202-
isDev && devtools(),
203201
TanStackRouterVite({
204202
target: "react",
205203
autoCodeSplitting: true,

apps/code/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@
4747
"@storybook/addon-a11y": "10.4.1",
4848
"@storybook/addon-docs": "10.4.1",
4949
"@storybook/react-vite": "10.4.1",
50-
"@tanstack/devtools-vite": "^0.7.0",
5150
"@testing-library/jest-dom": "^6.9.1",
5251
"@testing-library/react": "^16.3.0",
5352
"@testing-library/user-event": "^14.6.1",
@@ -138,6 +137,7 @@
138137
"react": "19.2.6",
139138
"react-dom": "19.2.6",
140139
"react-hotkeys-hook": "^4.4.4",
140+
"react-scan": "^0.5.6",
141141
"reflect-metadata": "^0.2.2",
142142
"semver": "^7.8.1",
143143
"shadcn": "^4.1.2",
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
#!/usr/bin/env node
2+
// Renders the "Downloads" section appended to GitHub release notes: one
3+
// markdown table per OS with a direct download link, blockmap link, and
4+
// SHA-256 per installer. Input is a directory of sha256sum/shasum output
5+
// files collected from the publish jobs in code-release.yml — the asset
6+
// patterns below must cover every file those jobs checksum.
7+
import { readdirSync, readFileSync, realpathSync } from "node:fs";
8+
import { join } from "node:path";
9+
import { fileURLToPath } from "node:url";
10+
11+
const DOWNLOAD_BASE = "https://github.com/PostHog/code/releases/download";
12+
13+
const ASSET_KINDS = [
14+
{ pattern: /-mac\.dmg$/, os: "macos", pkg: "DMG", pkgOrder: 0 },
15+
{ pattern: /-mac\.zip$/, os: "macos", pkg: "ZIP", pkgOrder: 1 },
16+
{
17+
pattern: /-win\.exe$/,
18+
os: "windows",
19+
pkg: "Installer (.exe)",
20+
pkgOrder: 0,
21+
},
22+
{ pattern: /\.AppImage$/, os: "linux", pkg: "AppImage", pkgOrder: 0 },
23+
{ pattern: /\.deb$/, os: "linux", pkg: "Debian (.deb)", pkgOrder: 1 },
24+
{ pattern: /\.rpm$/, os: "linux", pkg: "RPM (.rpm)", pkgOrder: 2 },
25+
];
26+
27+
const OS_SECTIONS = [
28+
// macOS sorts by arch first: users pick their chip, then a format.
29+
// Linux sorts by package first: the distro dictates deb/rpm/AppImage.
30+
{
31+
os: "macos",
32+
heading: "macOS",
33+
archOrder: ["arm64", "x64"],
34+
archFirst: true,
35+
},
36+
{
37+
os: "windows",
38+
heading: "Windows",
39+
archOrder: ["x64", "arm64"],
40+
archFirst: false,
41+
},
42+
{
43+
os: "linux",
44+
heading: "Linux",
45+
archOrder: ["x64", "arm64"],
46+
archFirst: false,
47+
},
48+
];
49+
50+
const ARCH_LABELS = {
51+
macos: { arm64: "Apple Silicon (arm64)", x64: "Intel (x64)" },
52+
windows: { arm64: "arm64", x64: "x64" },
53+
linux: { arm64: "arm64", x64: "x64" },
54+
};
55+
56+
// Parses `sha256sum`/`shasum -a 256` output into a filename -> sha map.
57+
export function parseChecksums(text) {
58+
const checksums = new Map();
59+
for (const line of text.split("\n")) {
60+
const match = line.trim().match(/^([0-9a-f]{64})[ *]+(.+)$/);
61+
if (match) checksums.set(match[2], match[1]);
62+
}
63+
return checksums;
64+
}
65+
66+
function detectArch(name) {
67+
if (/aarch64|arm64/.test(name)) return "arm64";
68+
if (/x86_64|amd64|x64/.test(name)) return "x64";
69+
return "unknown";
70+
}
71+
72+
export function buildDownloadTables(version, checksums) {
73+
const base = `${DOWNLOAD_BASE}/v${version.replace(/^v/, "")}`;
74+
const rows = { macos: [], windows: [], linux: [] };
75+
76+
for (const [name, sha] of checksums) {
77+
if (name.endsWith(".blockmap")) continue;
78+
const kind = ASSET_KINDS.find((k) => k.pattern.test(name));
79+
if (!kind) continue;
80+
const arch = detectArch(name);
81+
const blockmapName = `${name}.blockmap`;
82+
const blockmap = checksums.has(blockmapName)
83+
? `[blockmap](${base}/${blockmapName})`
84+
: "—";
85+
rows[kind.os].push({
86+
name,
87+
arch,
88+
pkgOrder: kind.pkgOrder,
89+
cells: [
90+
kind.pkg,
91+
ARCH_LABELS[kind.os][arch] ?? arch,
92+
`[${name}](${base}/${name})`,
93+
blockmap,
94+
// Abbreviated sha; the link title shows the full hash on hover.
95+
`[\`${sha.slice(0, 6)}\`](${base}/${name} "${sha}")`,
96+
],
97+
});
98+
}
99+
100+
const sections = [];
101+
for (const { os, heading, archOrder, archFirst } of OS_SECTIONS) {
102+
if (rows[os].length === 0) continue;
103+
const archRank = (row) => {
104+
const rank = archOrder.indexOf(row.arch);
105+
return rank === -1 ? archOrder.length : rank;
106+
};
107+
rows[os].sort((a, b) => {
108+
const aKey = archFirst
109+
? [archRank(a), a.pkgOrder]
110+
: [a.pkgOrder, archRank(a)];
111+
const bKey = archFirst
112+
? [archRank(b), b.pkgOrder]
113+
: [b.pkgOrder, archRank(b)];
114+
return (
115+
aKey[0] - bKey[0] || aKey[1] - bKey[1] || a.name.localeCompare(b.name)
116+
);
117+
});
118+
sections.push(
119+
[
120+
`### ${heading}`,
121+
"",
122+
"| Package | Architecture | Download | Blockmap | SHA-256 |",
123+
"| --- | --- | --- | --- | --- |",
124+
...rows[os].map((row) => `| ${row.cells.join(" | ")} |`),
125+
].join("\n"),
126+
);
127+
}
128+
129+
if (sections.length === 0) return "";
130+
return `## Downloads\n\n${sections.join("\n\n")}\n`;
131+
}
132+
133+
function main() {
134+
const [, , version, checksumsDir] = process.argv;
135+
136+
if (!version || !checksumsDir) {
137+
console.error(
138+
"Usage: generate-release-download-tables.mjs <version> <checksums-dir>",
139+
);
140+
process.exit(1);
141+
}
142+
143+
const files = readdirSync(checksumsDir)
144+
.filter((name) => name.endsWith(".txt"))
145+
.sort();
146+
const text = files
147+
.map((name) => readFileSync(join(checksumsDir, name), "utf8"))
148+
.join("\n");
149+
const checksums = parseChecksums(text);
150+
151+
for (const name of checksums.keys()) {
152+
if (
153+
!name.endsWith(".blockmap") &&
154+
!ASSET_KINDS.some((kind) => kind.pattern.test(name))
155+
) {
156+
console.error(`Skipping unrecognized artifact: ${name}`);
157+
}
158+
}
159+
160+
const markdown = buildDownloadTables(version, checksums);
161+
if (!markdown) {
162+
console.error(`No release artifacts found in ${checksumsDir}`);
163+
process.exit(1);
164+
}
165+
process.stdout.write(markdown);
166+
}
167+
168+
if (
169+
process.argv[1] &&
170+
realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)
171+
) {
172+
main();
173+
}

0 commit comments

Comments
 (0)