8aaa62c794
* feat(session-export): scaffold module with config constants * feat(session-export): add zstd compression wrapper * feat(session-export): event and envelope type definitions * feat(session-export): eligibility check with kill-switch * feat(session-export): org signal collector with auth resolver * feat(session-export): worker SQLite schema and storage helpers * feat(session-export): content-addressed chunker with zstd dedup * feat(session-export): client-side light scrubber * feat(session-export): IPC contract and inbox with back-pressure * feat(session-export): persist scrubbed events with chunked payloads * feat(session-export): worker entry point with inbox drain loop * feat(session-export): main-thread capture module * feat(session-export): workspace baseline and delta fibers * feat(session-export): sync subscriber and tool io chunking * feat(session-export): bootstrap wiring and compaction hook * feat(session-export): wire capture hooks into sessions * feat(session-export): uploader and buffer cap * chore(session-export): annotate shared session hooks * changeset(session-export): add release note * fix(session-export): keep bootstrap non-blocking without instance context * feat(session-export): respawn worker after failures * test(session-export): add performance budget assertions * test(session-export): add worker end-to-end smoke test * fix(session-export): strip identity and high-risk baseline paths * test(session-export): gate perf assertions for stable sweeps * fix(session-export): bundle worker in single-file builds * fix(session-export): make capture envelopes cloneable * fix(session-export): drain worker on CLI shutdown * feat(session-export): capture workspace baseline and deltas * fix(session-export): preserve request metadata * test(session-export): cover request metadata capture * feat(cli): send indexed session export batches * feat(cli): authorize session export uploads * fix(cli): flush session export shutdown uploads * feat(cli): optimize session export replay payloads * fix(cli): include session export surface metadata * fix(session-export): decrement chunk refs after upload decRefChunks was never called, so chunk ref_count stayed at 1 (or higher with dedup) and DELETE FROM chunk WHERE ref_count <= 0 never matched. Chunks accumulated in the local SQLite buffer until the 50 GB cap. Call decRefChunks alongside markUploaded so deleteUploaded can reclaim the rows. * fix(session-export): add periodic uploader flush timer flushIntervalMs and retryBackoffMaxMs were both defined in config and neither was referenced anywhere; scheduleFlush only ran on inbound events or reconnect. After a 5xx or network failure the row was backed off for 1 s, but if no further event arrived the retry never fired and the events stranded until the CLI restarted. Drive a periodic flush from a setInterval, unref the handle so it doesn't pin the process, and clear it from a new dispose() hook the worker calls on shutdown. * fix(session-export): stop emitting absolute workspace root in baseline CaptureMetadata.root was the literal absolute filesystem path (/Users/<name>/Projects/<repo>), shipped in every workspace_baseline_completed event and not stripped by handlers' identity filter. The field was set but never read anywhere downstream — file paths in the baseline are already relative, so the root added no replay signal. Remove the field outright. * fix(session-export): cap pendingEvents result set The SELECT had no LIMIT clause, so under a backlog (network outage, crashed receiver) it would materialize the full pending table into a JavaScript array before the byte-limit truncation applied. With a 50 GB buffer cap that is hundreds of MB of heap inside the worker per drain. Add LIMIT 500 — the drain loop already re-queries until empty, so no events are missed. * fix(session-export): exponential retry backoff up to retryBackoffMaxMs Both the 5xx and network-error branches always retried after the floor delay regardless of how many attempts had already failed, and retryBackoffMaxMs was unreferenced. During a sustained outage every session re-tried at roughly 1 Hz against the dead receiver. Surface upload_attempts on EventRow and compute the next delay as min * 2^attempts capped at max. * fix(session-export): evict superseded workspace snapshots on remember createWorkspaceProvider retained every captured snapshot — in-memory and inside the persisted state file — even after the session moved on to a newer one. For a 1k-file repo over a 100-turn session that is ~2 GB of unreachable heap plus a state file that grows monotonically. Drop the previous snapshot for the session on remember() when no other session still references it. * fix(session-export): anchor aws_secret_key scrubber to key name The bare 40-char base64 pattern matched every 40-character hex string, including all git commit SHAs. Tool outputs, diffs, and conversation messages were silently rewritten as <<REDACTED:aws_secret_key>>, destroying lineage information in training data. Require the key name context — naked secrets in unstructured text are rare and the .env / .aws/credentials high-risk path strip already covers the common case. * fix(session-export): preserve root linkage in SyncSubscriber events SyncSubscriber hardcoded rootSessionId = sessionId on every tool, permission, and feedback event, so sub-agent sessions lost their root linkage and a future training pipeline could not reconstruct the agent topology from these side-channel events. Expose the rootSessionId mapping from Capture and plumb it through the same pattern as getTurnId. * fix(session-export): atomic chunk GC after upload markUploaded + decRefChunks + deleteUploaded were three separate SQL statements; a crash between markUploaded and decRefChunks would leave events flagged uploaded (never retried) and chunks with stale ref_count (never reclaimed by deleteUploaded). Bundle the three calls into a single transactional commitUploaded helper so either all three land or none of them do. * fix(session-export): wait on transient sqlite locks * fix(session-export): snapshot current workspace directory * fix(cli): preserve Kilo model export metadata * fix(cli): send anon id for session export * fix(cli): fallback to telemetry anon id * chore(cli): annotate session export config test * chore: remove session export docs * fix(cli): harden session export uploads * fix(cli): preserve stream lifecycle for session export * fix(kilo-docs): exclude session export ingest link * fix(cli): restrict session export workspace sync to git repos * chore: remove session export changeset * fix(cli): tighten session export payload types * fix(cli): type session export model payloads * fix(cli): simplify session export cleanup * fix(cli): avoid session export shutdown race * refactor(cli): use drizzle for session export storage * fix(cli): finalize session export sqlite statements * fix(cli): link compaction exports to root sessions * fix(cli): stop exporting raw stream parts * fix(cli): prune stale workspace snapshots * refactor(cli): clarify chunk ref counting * test(cli): clarify dropped upload assertions * ci: avoid visual path filter action failure * fix(cli): preserve in-flight workspace snapshots * fix(cli): stop uploading baseline start events * fix(cli): trim redundant export metadata * fix(cli): trim workspace export bookkeeping * fix(cli): fold terminal outcome into tool exports * fix(cli): dedupe request context in export batches * fix(cli): normalize compaction export payloads * fix(cli): avoid duplicate tool result exports * test(cli): align session export expectations * fix(cli): run secretlint during session export scrubbing * fix(cli): keep retried export batches contiguous * fix(cli): include agent info in session exports * fix(cli): flush pending session exports on serve startup * fix(cli): drop exports when scrubbing fails * fix(cli): narrow secretlint value extraction * fix(cli): limit exported agent info * test(cli): remove brittle agent export source assertion * fix(cli): ignore corrupt session export workspace state * fix(cli): keep session export close best effort * fix(cli): avoid following session export symlinks * fix(cli): preserve session export chunk ref counts * fix(cli): retry transient session export uploads * fix(cli): validate session export ingest endpoint * fix(cli): tolerate missing export token details * fix(cli): fail closed on session export org lookup * fix(cli): decode session export permission replies * fix(cli): finalize session export on stream close * fix(cli): bound session export baseline timeout * fix(cli): avoid persisting workspace file contents * fix(cli): bound workspace snapshot capture * fix(cli): validate session export worker messages * fix(cli): revoke stale session export eligibility * fix(cli): scope session export workspaces * fix(cli): extend session export shutdown flush * fix(cli): infer free Kilo models for export * fix(cli): avoid duplicate chunk refs * fix(cli): throttle session export uploads * fix(cli): harden session export capture * feat: disclose free model data collection (#10767) * feat: disclose free model data collection * chore(cli): document free model footer sorting * fix(vscode): add free model data translations * fix: simplify free model data label * fix: simplify data collection badges * fix: remove duplicate model info disclosure * fix: restore composer data tooltip * fix: align jetbrains data collection indicator * fix: align free model data indicators * fix(vscode): show data collection in model preview * fix: limit data indicators to kilo gateway * test(cli): relax prompt cancel timeout * test(cli): annotate prompt cancel timeout * test(cli): classify prompt queue runtime test * fix(cli): defer session export startup
398 lines
17 KiB
YAML
398 lines
17 KiB
YAML
name: Visual Regression Tests
|
|
|
|
on:
|
|
pull_request:
|
|
types: [opened, synchronize, reopened]
|
|
|
|
jobs:
|
|
check-paths:
|
|
name: Check changed paths
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
matched: ${{ steps.filter.outputs.matched }}
|
|
is_fork: ${{ steps.fork-check.outputs.is_fork }}
|
|
steps:
|
|
- uses: actions/checkout@v6 # kilocode_change
|
|
# kilocode_change start
|
|
- name: Check changed files
|
|
id: filter
|
|
env:
|
|
GH_TOKEN: ${{ github.token }}
|
|
PR: ${{ github.event.pull_request.number }}
|
|
run: |
|
|
matched=false
|
|
while IFS= read -r file; do
|
|
case "$file" in
|
|
packages/kilo-ui/*|packages/ui/*|packages/util/*|packages/sdk/js/*|packages/kilo-vscode/webview-ui/*|packages/kilo-vscode/.storybook/*|packages/kilo-vscode/tests/visual-regression*|packages/kilo-vscode/tests/permission-dock-dropdown*|packages/kilo-vscode/tests/accessibility*|packages/kilo-docs/public/img/screenshot-tests/*|.github/workflows/visual-regression.yml)
|
|
matched=true
|
|
break
|
|
;;
|
|
esac
|
|
done < <(gh api --paginate "repos/${GITHUB_REPOSITORY}/pulls/${PR}/files" --jq '.[].filename')
|
|
echo "matched=$matched" >> "$GITHUB_OUTPUT"
|
|
echo "matched=$matched"
|
|
# kilocode_change end
|
|
- name: Check if PR is from a fork
|
|
id: fork-check
|
|
run: |
|
|
if [ "${{ github.event.pull_request.head.repo.full_name }}" != "${{ github.repository }}" ]; then
|
|
echo "is_fork=true" >> "$GITHUB_OUTPUT"
|
|
else
|
|
echo "is_fork=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
visual-regression:
|
|
needs: check-paths
|
|
if: needs.check-paths.outputs.matched == 'true'
|
|
name: Visual Regression (kilo-ui)
|
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
|
timeout-minutes: 15
|
|
|
|
steps:
|
|
- name: Checkout (internal)
|
|
if: needs.check-paths.outputs.is_fork != 'true'
|
|
uses: actions/checkout@v6 # kilocode_change
|
|
with:
|
|
lfs: true
|
|
token: ${{ secrets.BOT_PAT }}
|
|
ref: ${{ github.head_ref }}
|
|
|
|
- name: Checkout (fork)
|
|
if: needs.check-paths.outputs.is_fork == 'true'
|
|
uses: actions/checkout@v6 # kilocode_change
|
|
with:
|
|
lfs: true
|
|
|
|
- name: Check if HEAD is a baseline update commit
|
|
if: needs.check-paths.outputs.is_fork != 'true'
|
|
id: check-baseline-commit
|
|
run: |
|
|
COMMIT_MSG=$(git log -1 --format=%s)
|
|
if [ "$COMMIT_MSG" = "chore: update visual regression baselines" ] || [ "$COMMIT_MSG" = "chore: update kilo-vscode visual regression baselines" ]; then
|
|
echo "is_baseline_update=true" >> "$GITHUB_OUTPUT"
|
|
echo "HEAD commit is a baseline update commit — will not auto-commit again."
|
|
else
|
|
echo "is_baseline_update=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache Bun modules
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: ~/.bun/install/cache
|
|
key: bun-${{ hashFiles('bun.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Cache Playwright browsers
|
|
id: playwright-cache
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-${{ hashFiles('packages/kilo-ui/package.json') }}
|
|
|
|
- name: Install Playwright browsers
|
|
if: steps.playwright-cache.outputs.cache-hit != 'true'
|
|
run: bunx playwright install chromium
|
|
working-directory: packages/kilo-ui
|
|
|
|
- name: Install Playwright system deps
|
|
run: bunx playwright install-deps chromium
|
|
working-directory: packages/kilo-ui
|
|
|
|
- name: Cache Storybook build
|
|
id: storybook-cache
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: packages/kilo-ui/storybook-static
|
|
key: storybook-${{ hashFiles('packages/kilo-ui/src/**', 'packages/kilo-ui/.storybook/**', 'packages/ui/src/**', 'packages/kilo-ui/package.json') }}
|
|
|
|
- name: Build Storybook
|
|
if: steps.storybook-cache.outputs.cache-hit != 'true'
|
|
run: bun run build-storybook
|
|
working-directory: packages/kilo-ui
|
|
|
|
- name: Generate baselines for new/missing stories
|
|
run: bun run test:visual:update
|
|
working-directory: packages/kilo-ui
|
|
env:
|
|
CI: true
|
|
PLAYWRIGHT_WORKERS: "4"
|
|
|
|
- name: Remove stale baselines for deleted stories
|
|
run: |
|
|
node -e "
|
|
const fs = require('fs'), path = require('path');
|
|
const idx = JSON.parse(fs.readFileSync('storybook-static/index.json', 'utf8'));
|
|
const stories = Object.values(idx.entries || idx.stories || {}).filter(s => s.id && !s.id.endsWith('--docs'));
|
|
const expected = new Set(stories.map(s => { const [c,v] = s.id.split('--'); return c + '/' + v + '-chromium-linux.png'; }));
|
|
const dir = '../kilo-docs/public/img/screenshot-tests/kilo-ui/visual-regression';
|
|
if (!fs.existsSync(dir)) process.exit(0);
|
|
for (const component of fs.readdirSync(dir)) {
|
|
const cdir = path.join(dir, component);
|
|
if (!fs.statSync(cdir).isDirectory()) continue;
|
|
for (const file of fs.readdirSync(cdir)) {
|
|
const rel = component + '/' + file;
|
|
if (file.endsWith('.png') && !expected.has(rel)) { console.log('Removing stale baseline:', rel); fs.unlinkSync(path.join(cdir, file)); }
|
|
}
|
|
}
|
|
"
|
|
working-directory: packages/kilo-ui
|
|
|
|
- name: Check for baseline changes (fork PRs)
|
|
if: needs.check-paths.outputs.is_fork == 'true'
|
|
run: |
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-ui/
|
|
if git diff --cached --quiet; then
|
|
echo "No visual regression detected."
|
|
else
|
|
echo "::error::Visual regression detected. Screenshot baselines have changed."
|
|
echo "::error::Since this PR is from a fork, updated screenshots cannot be committed automatically."
|
|
echo "::error::Please ask a Kilo developer for help updating the screenshots."
|
|
git diff --cached --stat
|
|
exit 1
|
|
fi
|
|
|
|
- name: Fail if baselines still changing after auto-update
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.check-baseline-commit.outputs.is_baseline_update == 'true'
|
|
run: |
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-ui/
|
|
if git diff --cached --quiet; then
|
|
echo "Baselines are stable after auto-update."
|
|
else
|
|
echo "::error::Visual regression baselines changed again after a previous auto-update commit."
|
|
echo "::error::This indicates non-deterministic screenshots that would cause an infinite update loop."
|
|
echo "::error::Please investigate the flaky screenshots and add non-deterministic stories to the SKIP set."
|
|
git diff --cached --stat
|
|
exit 1
|
|
fi
|
|
|
|
- name: Commit and push new baselines (if any)
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.check-baseline-commit.outputs.is_baseline_update != 'true'
|
|
id: commit-baselines
|
|
env:
|
|
GH_TOKEN: ${{ secrets.BOT_PAT }}
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-ui/
|
|
if git diff --cached --quiet; then
|
|
echo "No new baselines — nothing to commit."
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
git commit -m "chore: update visual regression baselines"
|
|
git lfs push --all origin
|
|
git push --no-verify
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Fail if baselines changed
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.commit-baselines.outputs.changed == 'true'
|
|
run: |
|
|
echo "::error::Visual regression baselines changed. New baselines have been committed to the branch. Please pull and review."
|
|
exit 1
|
|
|
|
- name: Upload test results on failure
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7 # kilocode_change
|
|
with:
|
|
name: visual-regression-results
|
|
path: packages/kilo-ui/test-results/
|
|
retention-days: 7
|
|
|
|
visual-regression-vscode:
|
|
needs: check-paths
|
|
if: needs.check-paths.outputs.matched == 'true'
|
|
name: Visual Regression (kilo-vscode webview)
|
|
runs-on: blacksmith-4vcpu-ubuntu-2404
|
|
timeout-minutes: 15
|
|
|
|
steps:
|
|
- name: Checkout (internal)
|
|
if: needs.check-paths.outputs.is_fork != 'true'
|
|
uses: actions/checkout@v6 # kilocode_change
|
|
with:
|
|
lfs: true
|
|
token: ${{ secrets.BOT_PAT }}
|
|
ref: ${{ github.head_ref }}
|
|
|
|
- name: Checkout (fork)
|
|
if: needs.check-paths.outputs.is_fork == 'true'
|
|
uses: actions/checkout@v6 # kilocode_change
|
|
with:
|
|
lfs: true
|
|
|
|
- name: Check if HEAD is a baseline update commit
|
|
if: needs.check-paths.outputs.is_fork != 'true'
|
|
id: check-baseline-commit-vscode
|
|
run: |
|
|
COMMIT_MSG=$(git log -1 --format=%s)
|
|
if [ "$COMMIT_MSG" = "chore: update visual regression baselines" ] || [ "$COMMIT_MSG" = "chore: update kilo-vscode visual regression baselines" ]; then
|
|
echo "is_baseline_update=true" >> "$GITHUB_OUTPUT"
|
|
echo "HEAD commit is a baseline update commit — will not auto-commit again."
|
|
else
|
|
echo "is_baseline_update=false" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Setup Bun
|
|
uses: oven-sh/setup-bun@v2
|
|
with:
|
|
bun-version: latest
|
|
|
|
- name: Cache Bun modules
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: ~/.bun/install/cache
|
|
key: bun-${{ hashFiles('bun.lock') }}
|
|
|
|
- name: Install dependencies
|
|
run: bun install
|
|
|
|
- name: Cache Playwright browsers
|
|
id: playwright-cache-vscode
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: ~/.cache/ms-playwright
|
|
key: playwright-vscode-${{ hashFiles('packages/kilo-vscode/package.json') }}
|
|
|
|
- name: Install Playwright browsers
|
|
if: steps.playwright-cache-vscode.outputs.cache-hit != 'true'
|
|
run: bunx playwright install chromium
|
|
working-directory: packages/kilo-vscode
|
|
|
|
- name: Install Playwright system deps
|
|
run: bunx playwright install-deps chromium
|
|
working-directory: packages/kilo-vscode
|
|
|
|
- name: Cache Storybook build
|
|
id: storybook-cache-vscode
|
|
uses: actions/cache@v5 # kilocode_change
|
|
with:
|
|
path: packages/kilo-vscode/storybook-static
|
|
key: storybook-vscode-${{ hashFiles('packages/kilo-vscode/webview-ui/src/**', 'packages/kilo-vscode/.storybook/**', 'packages/kilo-ui/src/**', 'packages/ui/src/**', 'packages/kilo-vscode/package.json') }}
|
|
|
|
- name: Build Storybook
|
|
if: steps.storybook-cache-vscode.outputs.cache-hit != 'true'
|
|
run: bun run build-storybook
|
|
working-directory: packages/kilo-vscode
|
|
|
|
- name: Generate baselines and enforce webview accessibility checks # kilocode_change
|
|
run: bun run test:visual:update
|
|
working-directory: packages/kilo-vscode
|
|
env:
|
|
CI: true
|
|
PLAYWRIGHT_WORKERS: "4"
|
|
|
|
- name: Remove stale baselines for deleted stories
|
|
run: |
|
|
node -e "
|
|
const fs = require('fs'), path = require('path');
|
|
const idx = JSON.parse(fs.readFileSync('storybook-static/index.json', 'utf8'));
|
|
const stories = Object.values(idx.entries || idx.stories || {}).filter(s => s.id && !s.id.endsWith('--docs'));
|
|
const expected = new Set(stories.map(s => { const [c,v] = s.id.split('--'); return c + '/' + v + '-chromium-linux.png'; }));
|
|
const dir = '../kilo-docs/public/img/screenshot-tests/kilo-vscode/visual-regression';
|
|
if (!fs.existsSync(dir)) process.exit(0);
|
|
for (const component of fs.readdirSync(dir)) {
|
|
const cdir = path.join(dir, component);
|
|
if (!fs.statSync(cdir).isDirectory()) continue;
|
|
for (const file of fs.readdirSync(cdir)) {
|
|
const rel = component + '/' + file;
|
|
if (file.endsWith('.png') && !expected.has(rel)) { console.log('Removing stale baseline:', rel); fs.unlinkSync(path.join(cdir, file)); }
|
|
}
|
|
}
|
|
"
|
|
working-directory: packages/kilo-vscode
|
|
|
|
- name: Remove stale baselines for permission-dock-dropdown tests
|
|
run: |
|
|
node -e "
|
|
const fs = require('fs');
|
|
const specPath = 'tests/permission-dock-dropdown.spec.ts';
|
|
const expected = new Set();
|
|
if (fs.existsSync(specPath)) {
|
|
const spec = fs.readFileSync(specPath, 'utf8');
|
|
const re = /toHaveScreenshot\(\[([^\]]+)\]\)/g;
|
|
let m;
|
|
while ((m = re.exec(spec)) !== null) {
|
|
const parts = m[1].split(',').map(s => s.trim().replace(/[\"']/g, ''));
|
|
const file = parts[parts.length - 1];
|
|
if (file) expected.add(file.replace(/\.png$/, '-chromium-linux.png'));
|
|
}
|
|
}
|
|
const dir = '../kilo-docs/public/img/screenshot-tests/kilo-vscode/permission-dock-dropdown';
|
|
if (!fs.existsSync(dir)) process.exit(0);
|
|
for (const file of fs.readdirSync(dir)) {
|
|
if (file.endsWith('.png') && !expected.has(file)) {
|
|
console.log('Removing stale baseline:', file);
|
|
fs.unlinkSync(dir + '/' + file);
|
|
}
|
|
}
|
|
"
|
|
working-directory: packages/kilo-vscode
|
|
|
|
- name: Check for baseline changes (fork PRs)
|
|
if: needs.check-paths.outputs.is_fork == 'true'
|
|
run: |
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/
|
|
if git diff --cached --quiet; then
|
|
echo "No visual regression detected."
|
|
else
|
|
echo "::error::Visual regression detected. Screenshot baselines have changed."
|
|
echo "::error::Since this PR is from a fork, updated screenshots cannot be committed automatically."
|
|
echo "::error::Please ask a Kilo developer for help updating the screenshots."
|
|
git diff --cached --stat
|
|
exit 1
|
|
fi
|
|
|
|
- name: Fail if baselines still changing after auto-update
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.check-baseline-commit-vscode.outputs.is_baseline_update == 'true'
|
|
run: |
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/
|
|
if git diff --cached --quiet; then
|
|
echo "Baselines are stable after auto-update."
|
|
else
|
|
echo "::error::Visual regression baselines changed again after a previous auto-update commit."
|
|
echo "::error::This indicates non-deterministic screenshots that would cause an infinite update loop."
|
|
echo "::error::Please investigate the flaky screenshots and add non-deterministic stories to the SKIP set."
|
|
git diff --cached --stat
|
|
exit 1
|
|
fi
|
|
|
|
- name: Commit and push new baselines (if any)
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.check-baseline-commit-vscode.outputs.is_baseline_update != 'true'
|
|
id: commit-baselines-vscode
|
|
env:
|
|
GH_TOKEN: ${{ secrets.BOT_PAT }}
|
|
run: |
|
|
git config user.name "github-actions[bot]"
|
|
git config user.email "github-actions[bot]@users.noreply.github.com"
|
|
git add packages/kilo-docs/public/img/screenshot-tests/kilo-vscode/
|
|
if git diff --cached --quiet; then
|
|
echo "No new baselines — nothing to commit."
|
|
echo "changed=false" >> "$GITHUB_OUTPUT"
|
|
else
|
|
git commit -m "chore: update kilo-vscode visual regression baselines"
|
|
git lfs push --all origin
|
|
git push --no-verify
|
|
echo "changed=true" >> "$GITHUB_OUTPUT"
|
|
fi
|
|
|
|
- name: Fail if baselines changed
|
|
if: needs.check-paths.outputs.is_fork != 'true' && steps.commit-baselines-vscode.outputs.changed == 'true'
|
|
run: |
|
|
echo "::error::Visual regression baselines changed. New baselines have been committed to the branch. Please pull and review."
|
|
exit 1
|
|
|
|
- name: Upload test results on failure
|
|
if: failure()
|
|
uses: actions/upload-artifact@v7 # kilocode_change
|
|
with:
|
|
name: visual-regression-vscode-results
|
|
path: packages/kilo-vscode/test-results/
|
|
retention-days: 7
|