fix(ci-setup): stop overselling the CI->server index delivery (P1)

The generated CI uploads .gitnexus/ as a workflow artifact, but nothing
delivers it to the running server's persistent volume — yet GITNEXUS.md
claimed the volume is "updated when the volume-sharing mechanism (rsync,
artifact download, or live-mount) delivers a fresh index", naming three
mechanisms the wizard never generates. A team following the doc verbatim
gets a server serving an empty/stale index forever, with no loud failure.

Replace that prose with an explicit "the wizard does not automate index
delivery — it is a required operator step" statement plus a commented,
target-matched, copy-adaptable example: for Docker, an on-server scheduled
re-index (or `docker compose cp` of the downloaded artifact); for Azure
Container App, `az storage file upload-batch` to the mounted file share.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Gergo Magyar 2026-06-14 09:04:25 +00:00
parent 2f7d62ba92
commit 7808a1a351
2 changed files with 70 additions and 2 deletions

View file

@ -410,6 +410,38 @@ Copy the MCP entry from \`.claude/gitnexus-mcp-snippet.json\` into \`~/.claude/s
Replace \`<GITNEXUS_HOST>\` with the server's IP or hostname.`;
const dockerDelivery = `**Docker:** the simplest option is to re-index on the server host directly, so the
\`gitnexus-data\` volume stays fresh without any artifact handoff:
\`\`\`sh
# On the server, on a schedule (e.g. a cron entry):
# 0 * * * * cd /path/to/repo && npx gitnexus@latest analyze --skills
\`\`\`
Or download the CI artifact and copy it into the running container's volume:
\`\`\`sh
# gh run download --name "gitnexus-index-<sha>" --dir ./gitnexus-index
# docker compose cp ./gitnexus-index/. gitnexus:/data/gitnexus/
\`\`\``;
const acaDelivery = `**Azure Container App:** push the index to the Azure File share the app mounts:
\`\`\`sh
# From a machine with ./.gitnexus and an \`az login\` session:
# az storage file upload-batch \\
# --account-name "$STORAGE_ACCOUNT" \\
# --destination "$FILE_SHARE" \\
# --source ./.gitnexus
\`\`\``;
const deliverySection =
opts.deploy === 'azure-container-app'
? acaDelivery
: opts.deploy === 'both'
? `${dockerDelivery}\n\n${acaDelivery}`
: dockerDelivery;
return `# GitNexus — Shared Code Intelligence Server
GitNexus builds a knowledge graph of this repository and serves it as an MCP (Model Context Protocol)
@ -474,8 +506,12 @@ If the index is stale (CI hasn't run since the last push), Claude Code will stil
on a slightly outdated graph. The staleness check step in the workflow fails the run if indexing produced
no output, so stale-index PRs are blocked at CI.
For the shared server: the container reads the index from the persistent volume, which is updated
when the volume-sharing mechanism (rsync, artifact download, or live-mount) delivers a fresh index.
> **The wizard does not automate index delivery to the shared server.** CI uploads \`.gitnexus/\` as a
> workflow artifact; the running server reads its own persistent volume, and nothing connects the two
> automatically. Delivering the fresh index to the server's volume is a required operator step — pick
> the approach that matches your deployment (the commands below are commented; adapt paths/names):
${deliverySection}
---

View file

@ -25,6 +25,38 @@ function makeOpts(overrides?: Partial<CiSetupOptions>): CiSetupOptions {
};
}
function gitnexusMd(overrides?: Partial<CiSetupOptions>): string {
const files = generateFiles(makeOpts(overrides), DEFAULT_DETECT);
const md = files.find((f) => f.relativePath === 'GITNEXUS.md');
if (!md) throw new Error('GITNEXUS.md not generated');
return md.content;
}
describe('GITNEXUS.md index delivery (U7)', () => {
it('does not oversell auto-delivery with a non-existent volume-sharing mechanism', () => {
const content = gitnexusMd();
expect(content).not.toContain('volume-sharing mechanism');
expect(content).toContain('does not automate index delivery');
});
it('docker deploy shows an on-server delivery example (docker compose cp)', () => {
const content = gitnexusMd({ deploy: 'docker' });
expect(content).toContain('docker compose cp');
expect(content).not.toContain('az storage file upload-batch');
});
it('ACA deploy shows an az storage file upload-batch example', () => {
const content = gitnexusMd({ deploy: 'azure-container-app' });
expect(content).toContain('az storage file upload-batch');
});
it('both deploy shows both delivery paths', () => {
const content = gitnexusMd({ deploy: 'both' });
expect(content).toContain('docker compose cp');
expect(content).toContain('az storage file upload-batch');
});
});
describe('generateFiles', () => {
describe('GitHub Actions workflow', () => {
it('generates with correct port in healthcheck', () => {